1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package com.sun.java.util.jar.pack;
27
28 import com.sun.java.util.jar.pack.ConstantPool.Entry;
29 import com.sun.java.util.jar.pack.ConstantPool.Index;
30 import com.sun.java.util.jar.pack.Package.Class.Field;
31 import java.io.BufferedOutputStream;
32 import java.io.ByteArrayInputStream;
33 import java.io.ByteArrayOutputStream;
34 import java.io.EOFException;
35 import java.io.File;
36 import java.io.FileOutputStream;
37 import java.io.FilterInputStream;
38 import java.io.FilterOutputStream;
39 import java.io.IOException;
40 import java.io.InputStream;
41 import java.io.OutputStream;
42 import java.io.PrintStream;
43 import java.util.ArrayList;
44 import java.util.Arrays;
45 import java.util.Collections;
46 import java.util.HashMap;
47 import java.util.List;
48 import java.util.Map;
49 import java.util.jar.Pack200;
50 import static com.sun.java.util.jar.pack.Constants.*;
51
52
53
54
55
56 abstract
57 class BandStructure {
58 static final int MAX_EFFORT = 9;
59 static final int MIN_EFFORT = 1;
60 static final int DEFAULT_EFFORT = 5;
61
62
63 PropMap p200 = Utils.currentPropMap();
64
65 int verbose = p200.getInteger(Utils.DEBUG_VERBOSE);
66 int effort = p200.getInteger(Pack200.Packer.EFFORT);
67 { if (effort == 0) effort = DEFAULT_EFFORT; }
68 boolean optDumpBands = p200.getBoolean(Utils.COM_PREFIX+"dump.bands");
69 boolean optDebugBands = p200.getBoolean(Utils.COM_PREFIX+"debug.bands");
70
71
72 boolean optVaryCodings = !p200.getBoolean(Utils.COM_PREFIX+"no.vary.codings");
73 boolean optBigStrings = !p200.getBoolean(Utils.COM_PREFIX+"no.big.strings");
74
75 abstract protected Index getCPIndex(byte tag);
76
77
78 private int packageMajver = -1;
79
80
81 public void initPackageMajver(int packageMajver) throws IOException {
82 assert(packageMajver > 0 && packageMajver < 0x10000);
83 if (this.packageMajver > 0) {
84 throw new IOException(
85 "Package majver is already initialized to " + this.packageMajver+
86 "; new setting is " + packageMajver);
87 }
88 this.packageMajver = packageMajver;
89 adjustToMajver();
90 }
91 public int getPackageMajver() {
92 if (packageMajver < 0) {
93 throw new RuntimeException("Package majver not yet initialized");
94 }
95 return packageMajver;
96 }
97
98 private final boolean isReader = this instanceof PackageReader;
99 protected BandStructure() {
100 }
101
102 final static Coding BYTE1 = Coding.of(1,256);
103
104 final static Coding CHAR3 = Coding.of(3,128);
105
106
107
108 final static Coding BCI5 = Coding.of(5,4);
109 final static Coding BRANCH5 = Coding.of(5,4,2);
110
111 final static Coding UNSIGNED5 = Coding.of(5,64);
112 final static Coding UDELTA5 = UNSIGNED5.getDeltaCoding();
113
114
115
116 final static Coding SIGNED5 = Coding.of(5,64,1);
117 final static Coding DELTA5 = SIGNED5.getDeltaCoding();
118
119
120 final static Coding MDELTA5 = Coding.of(5,64,2).getDeltaCoding();
121
122 final private static Coding[] basicCodings = {
123
124 null,
125
126
127 Coding.of(1,256,0),
128 Coding.of(1,256,1),
129 Coding.of(1,256,0).getDeltaCoding(),
130 Coding.of(1,256,1).getDeltaCoding(),
131 Coding.of(2,256,0),
132 Coding.of(2,256,1),
133 Coding.of(2,256,0).getDeltaCoding(),
134 Coding.of(2,256,1).getDeltaCoding(),
135 Coding.of(3,256,0),
136 Coding.of(3,256,1),
137 Coding.of(3,256,0).getDeltaCoding(),
138 Coding.of(3,256,1).getDeltaCoding(),
139 Coding.of(4,256,0),
140 Coding.of(4,256,1),
141 Coding.of(4,256,0).getDeltaCoding(),
142 Coding.of(4,256,1).getDeltaCoding(),
143
144
145 Coding.of(5, 4,0),
146 Coding.of(5, 4,1),
147 Coding.of(5, 4,2),
148 Coding.of(5, 16,0),
149 Coding.of(5, 16,1),
150 Coding.of(5, 16,2),
151 Coding.of(5, 32,0),
152 Coding.of(5, 32,1),
153 Coding.of(5, 32,2),
154 Coding.of(5, 64,0),
155 Coding.of(5, 64,1),
156 Coding.of(5, 64,2),
157 Coding.of(5,128,0),
158 Coding.of(5,128,1),
159 Coding.of(5,128,2),
160
161 Coding.of(5, 4,0).getDeltaCoding(),
162 Coding.of(5, 4,1).getDeltaCoding(),
163 Coding.of(5, 4,2).getDeltaCoding(),
164 Coding.of(5, 16,0).getDeltaCoding(),
165 Coding.of(5, 16,1).getDeltaCoding(),
166 Coding.of(5, 16,2).getDeltaCoding(),
167 Coding.of(5, 32,0).getDeltaCoding(),
168 Coding.of(5, 32,1).getDeltaCoding(),
169 Coding.of(5, 32,2).getDeltaCoding(),
170 Coding.of(5, 64,0).getDeltaCoding(),
171 Coding.of(5, 64,1).getDeltaCoding(),
172 Coding.of(5, 64,2).getDeltaCoding(),
173 Coding.of(5,128,0).getDeltaCoding(),
174 Coding.of(5,128,1).getDeltaCoding(),
175 Coding.of(5,128,2).getDeltaCoding(),
176
177
178 Coding.of(2,192,0),
179 Coding.of(2,224,0),
180 Coding.of(2,240,0),
181 Coding.of(2,248,0),
182 Coding.of(2,252,0),
183
184 Coding.of(2, 8,0).getDeltaCoding(),
185 Coding.of(2, 8,1).getDeltaCoding(),
186 Coding.of(2, 16,0).getDeltaCoding(),
187 Coding.of(2, 16,1).getDeltaCoding(),
188 Coding.of(2, 32,0).getDeltaCoding(),
189 Coding.of(2, 32,1).getDeltaCoding(),
190 Coding.of(2, 64,0).getDeltaCoding(),
191 Coding.of(2, 64,1).getDeltaCoding(),
192 Coding.of(2,128,0).getDeltaCoding(),
193 Coding.of(2,128,1).getDeltaCoding(),
194 Coding.of(2,192,0).getDeltaCoding(),
195 Coding.of(2,192,1).getDeltaCoding(),
196 Coding.of(2,224,0).getDeltaCoding(),
197 Coding.of(2,224,1).getDeltaCoding(),
198 Coding.of(2,240,0).getDeltaCoding(),
199 Coding.of(2,240,1).getDeltaCoding(),
200 Coding.of(2,248,0).getDeltaCoding(),
201 Coding.of(2,248,1).getDeltaCoding(),
202
203 Coding.of(3,192,0),
204 Coding.of(3,224,0),
205 Coding.of(3,240,0),
206 Coding.of(3,248,0),
207 Coding.of(3,252,0),
208
209 Coding.of(3, 8,0).getDeltaCoding(),
210 Coding.of(3, 8,1).getDeltaCoding(),
211 Coding.of(3, 16,0).getDeltaCoding(),
212 Coding.of(3, 16,1).getDeltaCoding(),
213 Coding.of(3, 32,0).getDeltaCoding(),
214 Coding.of(3, 32,1).getDeltaCoding(),
215 Coding.of(3, 64,0).getDeltaCoding(),
216 Coding.of(3, 64,1).getDeltaCoding(),
217 Coding.of(3,128,0).getDeltaCoding(),
218 Coding.of(3,128,1).getDeltaCoding(),
219 Coding.of(3,192,0).getDeltaCoding(),
220 Coding.of(3,192,1).getDeltaCoding(),
221 Coding.of(3,224,0).getDeltaCoding(),
222 Coding.of(3,224,1).getDeltaCoding(),
223 Coding.of(3,240,0).getDeltaCoding(),
224 Coding.of(3,240,1).getDeltaCoding(),
225 Coding.of(3,248,0).getDeltaCoding(),
226 Coding.of(3,248,1).getDeltaCoding(),
227
228 Coding.of(4,192,0),
229 Coding.of(4,224,0),
230 Coding.of(4,240,0),
231 Coding.of(4,248,0),
232 Coding.of(4,252,0),
233
234 Coding.of(4, 8,0).getDeltaCoding(),
235 Coding.of(4, 8,1).getDeltaCoding(),
236 Coding.of(4, 16,0).getDeltaCoding(),
237 Coding.of(4, 16,1).getDeltaCoding(),
238 Coding.of(4, 32,0).getDeltaCoding(),
239 Coding.of(4, 32,1).getDeltaCoding(),
240 Coding.of(4, 64,0).getDeltaCoding(),
241 Coding.of(4, 64,1).getDeltaCoding(),
242 Coding.of(4,128,0).getDeltaCoding(),
243 Coding.of(4,128,1).getDeltaCoding(),
244 Coding.of(4,192,0).getDeltaCoding(),
245 Coding.of(4,192,1).getDeltaCoding(),
246 Coding.of(4,224,0).getDeltaCoding(),
247 Coding.of(4,224,1).getDeltaCoding(),
248 Coding.of(4,240,0).getDeltaCoding(),
249 Coding.of(4,240,1).getDeltaCoding(),
250 Coding.of(4,248,0).getDeltaCoding(),
251 Coding.of(4,248,1).getDeltaCoding(),
252
253 null
254 };
255 final private static Map<Coding, Integer> basicCodingIndexes;
256 static {
257 assert(basicCodings[_meta_default] == null);
258 assert(basicCodings[_meta_canon_min] != null);
259 assert(basicCodings[_meta_canon_max] != null);
260 Map<Coding, Integer> map = new HashMap<>();
261 for (int i = 0; i < basicCodings.length; i++) {
262 Coding c = basicCodings[i];
263 if (c == null) continue;
264 assert(i >= _meta_canon_min);
265 assert(i <= _meta_canon_max);
266 map.put(c, i);
267 }
268 basicCodingIndexes = map;
269 }
270 public static Coding codingForIndex(int i) {
271 return i < basicCodings.length ? basicCodings[i] : null;
272 }
273 public static int indexOf(Coding c) {
274 Integer i = basicCodingIndexes.get(c);
275 if (i == null) return 0;
276 return i.intValue();
277 }
278 public static Coding[] getBasicCodings() {
279 return basicCodings.clone();
280 }
281
282 protected byte[] bandHeaderBytes;
283 protected int bandHeaderBytePos;
284 protected int bandHeaderBytePos0;
285
286 protected CodingMethod getBandHeader(int XB, Coding regularCoding) {
287 CodingMethod[] res = {null};
288
289 bandHeaderBytes[--bandHeaderBytePos] = (byte) XB;
290 bandHeaderBytePos0 = bandHeaderBytePos;
291
292 bandHeaderBytePos = parseMetaCoding(bandHeaderBytes,
293 bandHeaderBytePos,
294 regularCoding,
295 res);
296 return res[0];
297 }
298
299 public static int parseMetaCoding(byte[] bytes, int pos, Coding dflt, CodingMethod[] res) {
300 if ((bytes[pos] & 0xFF) == _meta_default) {
301 res[0] = dflt;
302 return pos+1;
303 }
304 int pos2;
305 pos2 = Coding.parseMetaCoding(bytes, pos, dflt, res);
306 if (pos2 > pos) return pos2;
307 pos2 = PopulationCoding.parseMetaCoding(bytes, pos, dflt, res);
308 if (pos2 > pos) return pos2;
309 pos2 = AdaptiveCoding.parseMetaCoding(bytes, pos, dflt, res);
310 if (pos2 > pos) return pos2;
311 throw new RuntimeException("Bad meta-coding op "+(bytes[pos]&0xFF));
312 }
313
314 static final int SHORT_BAND_HEURISTIC = 100;
315
316 public static final int NO_PHASE = 0;
317
318
319 public static final int COLLECT_PHASE = 1;
320 public static final int FROZEN_PHASE = 3;
321 public static final int WRITE_PHASE = 5;
322
323
324 public static final int EXPECT_PHASE = 2;
325 public static final int READ_PHASE = 4;
326 public static final int DISBURSE_PHASE = 6;
327
328 public static final int DONE_PHASE = 8;
329
330 static boolean phaseIsRead(int p) {
331 return (p % 2) == 0;
332 }
333 static int phaseCmp(int p0, int p1) {
334 assert((p0 % 2) == (p1 % 2) || (p0 % 8) == 0 || (p1 % 8) == 0);
335 return p0 - p1;
336 }
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359 abstract class Band {
360 private int phase = NO_PHASE;
361 private final String name;
362
363 private int valuesExpected;
364
365 protected long outputSize = -1;
366
367 final public Coding regularCoding;
368
369 final public int seqForDebug;
370 public int elementCountForDebug;
371
372
373 protected Band(String name, Coding regularCoding) {
374 this.name = name;
375 this.regularCoding = regularCoding;
376 this.seqForDebug = ++nextSeqForDebug;
377 if (verbose > 2)
378 Utils.log.fine("Band "+seqForDebug+" is "+name);
379
380 }
381
382 public Band init() {
383
384
385
386 if (isReader)
387 readyToExpect();
388 else
389 readyToCollect();
390 return this;
391 }
392
393
394 boolean isReader() { return isReader; }
395 int phase() { return phase; }
396 String name() { return name; }
397
398
399 public abstract int capacity();
400
401
402 protected abstract void setCapacity(int cap);
403
404
405 public abstract int length();
406
407 protected abstract int valuesRemainingForDebug();
408
409 public final int valuesExpected() {
410 return valuesExpected;
411 }
412
413
414 public final void writeTo(OutputStream out) throws IOException {
415 assert(assertReadyToWriteTo(this, out));
416 setPhase(WRITE_PHASE);
417
418 writeDataTo(out);
419 doneWriting();
420 }
421
422 abstract void chooseBandCodings() throws IOException;
423
424 public final long outputSize() {
425 if (outputSize >= 0) {
426 long size = outputSize;
427 assert(size == computeOutputSize());
428 return size;
429 }
430 return computeOutputSize();
431 }
432
433 protected abstract long computeOutputSize();
434
435 abstract protected void writeDataTo(OutputStream out) throws IOException;
436
437
438 void expectLength(int l) {
439 assert(assertPhase(this, EXPECT_PHASE));
440 assert(valuesExpected == 0);
441 assert(l >= 0);
442 valuesExpected = l;
443 }
444
445 void expectMoreLength(int l) {
446 assert(assertPhase(this, EXPECT_PHASE));
447 valuesExpected += l;
448 }
449
450
451
452
453 private void readyToCollect() {
454 setCapacity(1);
455 setPhase(COLLECT_PHASE);
456 }
457 protected void doneWriting() {
458 assert(assertPhase(this, WRITE_PHASE));
459 setPhase(DONE_PHASE);
460 }
461 private void readyToExpect() {
462 setPhase(EXPECT_PHASE);
463 }
464
465 public final void readFrom(InputStream in) throws IOException {
466 assert(assertReadyToReadFrom(this, in));
467 setCapacity(valuesExpected());
468 setPhase(READ_PHASE);
469
470 readDataFrom(in);
471 readyToDisburse();
472 }
473 abstract protected void readDataFrom(InputStream in) throws IOException;
474 protected void readyToDisburse() {
475 if (verbose > 1) Utils.log.fine("readyToDisburse "+this);
476 setPhase(DISBURSE_PHASE);
477 }
478 public void doneDisbursing() {
479 assert(assertPhase(this, DISBURSE_PHASE));
480 setPhase(DONE_PHASE);
481 }
482 public final void doneWithUnusedBand() {
483 if (isReader) {
484 assert(assertPhase(this, EXPECT_PHASE));
485 assert(valuesExpected() == 0);
486
487 setPhase(READ_PHASE);
488 setPhase(DISBURSE_PHASE);
489 setPhase(DONE_PHASE);
490 } else {
491 setPhase(FROZEN_PHASE);
492 }
493 }
494
495 protected void setPhase(int newPhase) {
496 assert(assertPhaseChangeOK(this, phase, newPhase));
497 this.phase = newPhase;
498 }
499
500 protected int lengthForDebug = -1;
501 public String toString() {
502 int length = (lengthForDebug != -1 ? lengthForDebug : length());
503 String str = name;
504 if (length != 0)
505 str += "[" + length + "]";
506 if (elementCountForDebug != 0)
507 str += "(" + elementCountForDebug + ")";
508 return str;
509 }
510 }
511
512 class ValueBand extends Band {
513 private int[] values;
514 private int length;
515 private int valuesDisbursed;
516
517 private CodingMethod bandCoding;
518 private byte[] metaCoding;
519
520 protected ValueBand(String name, Coding regularCoding) {
521 super(name, regularCoding);
522 }
523
524 public int capacity() {
525 return values == null ? -1 : values.length;
526 }
527
528
529 protected void setCapacity(int cap) {
530 assert(length <= cap);
531 if (cap == -1) { values = null; return; }
532 values = realloc(values, cap);
533 }
534
535 public int length() {
536 return length;
537 }
538 protected int valuesRemainingForDebug() {
539 return length - valuesDisbursed;
540 }
541 protected int valueAtForDebug(int i) {
542 return values[i];
543 }
544
545 void patchValue(int i, int value) {
546
547 assert(this == archive_header_S);
548 assert(i == AH_ARCHIVE_SIZE_HI || i == AH_ARCHIVE_SIZE_LO);
549 assert(i < length);
550 values[i] = value;
551 outputSize = -1;
552 }
553
554 protected void initializeValues(int[] values) {
555 assert(assertCanChangeLength(this));
556 assert(length == 0);
557 this.values = values;
558 this.length = values.length;
559 }
560
561
562 protected void addValue(int x) {
563 assert(assertCanChangeLength(this));
564 if (length == values.length)
565 setCapacity(length < 1000 ? length * 10 : length * 2);
566 values[length++] = x;
567 }
568
569 private boolean canVaryCoding() {
570 if (!optVaryCodings) return false;
571 if (length == 0) return false;
572
573 if (this == archive_header_0) return false;
574 if (this == archive_header_S) return false;
575 if (this == archive_header_1) return false;
576
577
578
579 return (regularCoding.min() <= -256 || regularCoding.max() >= 256);
580 }
581
582 private boolean shouldVaryCoding() {
583 assert(canVaryCoding());
584 if (effort < MAX_EFFORT && length < SHORT_BAND_HEURISTIC)
585 return false;
586 return true;
587 }
588
589 protected void chooseBandCodings() throws IOException {
590 boolean canVary = canVaryCoding();
591 if (!canVary || !shouldVaryCoding()) {
592 if (regularCoding.canRepresent(values, 0, length)) {
593 bandCoding = regularCoding;
594 } else {
595 assert(canVary);
596 if (verbose > 1)
597 Utils.log.fine("regular coding fails in band "+name());
598 bandCoding = UNSIGNED5;
599 }
600 outputSize = -1;
601 } else {
602 int[] sizes = {0,0};
603 bandCoding = chooseCoding(values, 0, length,
604 regularCoding, name(),
605 sizes);
606 outputSize = sizes[CodingChooser.BYTE_SIZE];
607 if (outputSize == 0)
608 outputSize = -1;
609 }
610
611
612 if (bandCoding != regularCoding) {
613 metaCoding = bandCoding.getMetaCoding(regularCoding);
614 if (verbose > 1) {
615 Utils.log.fine("alternate coding "+this+" "+bandCoding);
616 }
617 } else if (canVary &&
618 decodeEscapeValue(values[0], regularCoding) >= 0) {
619
620 metaCoding = defaultMetaCoding;
621 } else {
622
623 metaCoding = noMetaCoding;
624 }
625 if (metaCoding.length > 0
626 && (verbose > 2 || verbose > 1 && metaCoding.length > 1)) {
627 StringBuffer sb = new StringBuffer();
628 for (int i = 0; i < metaCoding.length; i++) {
629 if (i == 1) sb.append(" /");
630 sb.append(" ").append(metaCoding[i] & 0xFF);
631 }
632 Utils.log.fine(" meta-coding "+sb);
633 }
634
635 assert((outputSize < 0) ||
636 !(bandCoding instanceof Coding) ||
637 (outputSize == ((Coding)bandCoding)
638 .getLength(values, 0, length)))
639 : (bandCoding+" : "+
640 outputSize+" != "+
641 ((Coding)bandCoding).getLength(values, 0, length)
642 +" ?= "+getCodingChooser().computeByteSize(bandCoding,values,0,length)
643 );
644
645
646 if (metaCoding.length > 0) {
647
648
649
650 if (outputSize >= 0)
651 outputSize += computeEscapeSize();
652
653 for (int i = 1; i < metaCoding.length; i++) {
654 band_headers.putByte(metaCoding[i] & 0xFF);
655 }
656 }
657 }
658
659 protected long computeOutputSize() {
660 outputSize = getCodingChooser().computeByteSize(bandCoding,
661 values, 0, length);
662 assert(outputSize < Integer.MAX_VALUE);
663 outputSize += computeEscapeSize();
664 return outputSize;
665 }
666
667 protected int computeEscapeSize() {
668 if (metaCoding.length == 0) return 0;
669 int XB = metaCoding[0] & 0xFF;
670 int X = encodeEscapeValue(XB, regularCoding);
671 return regularCoding.setD(0).getLength(X);
672 }
673
674 protected void writeDataTo(OutputStream out) throws IOException {
675 if (length == 0) return;
676 long len0 = 0;
677 if (out == outputCounter) {
678 len0 = outputCounter.getCount();
679 }
680 if (metaCoding.length > 0) {
681 int XB = metaCoding[0] & 0xFF;
682
683
684
685 int X = encodeEscapeValue(XB, regularCoding);
686
687 regularCoding.setD(0).writeTo(out, X);
688 }
689 bandCoding.writeArrayTo(out, values, 0, length);
690 if (out == outputCounter) {
691 assert(outputSize == outputCounter.getCount() - len0)
692 : (outputSize+" != "+outputCounter.getCount()+"-"+len0);
693 }
694 if (optDumpBands) dumpBand();
695 }
696
697 protected void readDataFrom(InputStream in) throws IOException {
698 length = valuesExpected();
699 if (length == 0) return;
700 if (verbose > 1)
701 Utils.log.fine("Reading band "+this);
702 if (!canVaryCoding()) {
703 bandCoding = regularCoding;
704 metaCoding = noMetaCoding;
705 } else {
706 assert(in.markSupported());
707 in.mark(Coding.B_MAX);
708 int X = regularCoding.setD(0).readFrom(in);
709 int XB = decodeEscapeValue(X, regularCoding);
710 if (XB < 0) {
711
712 in.reset();
713 XB = _meta_default;
714 bandCoding = regularCoding;
715 metaCoding = noMetaCoding;
716 } else if (XB == _meta_default) {
717 bandCoding = regularCoding;
718 metaCoding = defaultMetaCoding;
719 } else {
720 if (verbose > 2)
721 Utils.log.fine("found X="+X+" => XB="+XB);
722 bandCoding = getBandHeader(XB, regularCoding);
723
724 int p0 = bandHeaderBytePos0;
725 int p1 = bandHeaderBytePos;
726 metaCoding = new byte[p1-p0];
727 System.arraycopy(bandHeaderBytes, p0,
728 metaCoding, 0, metaCoding.length);
729 }
730 }
731 if (bandCoding != regularCoding) {
732 if (verbose > 1)
733 Utils.log.fine(name()+": irregular coding "+bandCoding);
734 }
735 bandCoding.readArrayFrom(in, values, 0, length);
736 if (optDumpBands) dumpBand();
737 }
738
739 public void doneDisbursing() {
740 super.doneDisbursing();
741 values = null;
742 }
743
744 private void dumpBand() throws IOException {
745 assert(optDumpBands);
746 try (PrintStream ps = new PrintStream(getDumpStream(this, ".txt"))) {
747 String irr = (bandCoding == regularCoding) ? "" : " irregular";
748 ps.print("# length="+length+
749 " size="+outputSize()+
750 irr+" coding="+bandCoding);
751 if (metaCoding != noMetaCoding) {
752 StringBuffer sb = new StringBuffer();
753 for (int i = 0; i < metaCoding.length; i++) {
754 if (i == 1) sb.append(" /");
755 sb.append(" ").append(metaCoding[i] & 0xFF);
756 }
757 ps.print(" //header: "+sb);
758 }
759 printArrayTo(ps, values, 0, length);
760 }
761 try (OutputStream ds = getDumpStream(this, ".bnd")) {
762 bandCoding.writeArrayTo(ds, values, 0, length);
763 }
764 }
765
766
767 protected int getValue() {
768 assert(phase() == DISBURSE_PHASE);
769 assert(valuesDisbursed < length);
770 return values[valuesDisbursed++];
771 }
772
773
774 public void resetForSecondPass() {
775 assert(phase() == DISBURSE_PHASE);
776 assert(valuesDisbursed == length());
777 valuesDisbursed = 0;
778 }
779 }
780
781 class ByteBand extends Band {
782 private ByteArrayOutputStream bytes;
783 private ByteArrayOutputStream bytesForDump;
784 private InputStream in;
785
786 public ByteBand(String name) {
787 super(name, BYTE1);
788 }
789
790 public int capacity() {
791 return bytes == null ? -1 : Integer.MAX_VALUE;
792 }
793 protected void setCapacity(int cap) {
794 assert(bytes == null);
795 bytes = new ByteArrayOutputStream(cap);
796 }
797 public void destroy() {
798 lengthForDebug = length();
799 bytes = null;
800 }
801
802 public int length() {
803 return bytes == null ? -1 : bytes.size();
804 }
805 public void reset() {
806 bytes.reset();
807 }
808 protected int valuesRemainingForDebug() {
809 return (bytes == null) ? -1 : ((ByteArrayInputStream)in).available();
810 }
811
812 protected void chooseBandCodings() throws IOException {
813
814 assert(decodeEscapeValue(regularCoding.min(), regularCoding) < 0);
815 assert(decodeEscapeValue(regularCoding.max(), regularCoding) < 0);
816 }
817
818 protected long computeOutputSize() {
819
820 return bytes.size();
821 }
822
823 public void writeDataTo(OutputStream out) throws IOException {
824 if (length() == 0) return;
825 bytes.writeTo(out);
826 if (optDumpBands) dumpBand();
827 destroy();
828 }
829
830 private void dumpBand() throws IOException {
831 assert(optDumpBands);
832 try (OutputStream ds = getDumpStream(this, ".bnd")) {
833 if (bytesForDump != null)
834 bytesForDump.writeTo(ds);
835 else
836 bytes.writeTo(ds);
837 }
838 }
839
840 public void readDataFrom(InputStream in) throws IOException {
841 int vex = valuesExpected();
842 if (vex == 0) return;
843 if (verbose > 1) {
844 lengthForDebug = vex;
845 Utils.log.fine("Reading band "+this);
846 lengthForDebug = -1;
847 }
848 byte[] buf = new byte[Math.min(vex, 1<<14)];
849 while (vex > 0) {
850 int nr = in.read(buf, 0, Math.min(vex, buf.length));
851 if (nr < 0) throw new EOFException();
852 bytes.write(buf, 0, nr);
853 vex -= nr;
854 }
855 if (optDumpBands) dumpBand();
856 }
857
858 public void readyToDisburse() {
859 in = new ByteArrayInputStream(bytes.toByteArray());
860 super.readyToDisburse();
861 }
862
863 public void doneDisbursing() {
864 super.doneDisbursing();
865 if (optDumpBands
866 && bytesForDump != null && bytesForDump.size() > 0) {
867 try {
868 dumpBand();
869 } catch (IOException ee) {
870 throw new RuntimeException(ee);
871 }
872 }
873 in = null;
874 bytes = null;
875 bytesForDump = null;
876 }
877
878
879 public void setInputStreamFrom(InputStream in) throws IOException {
880 assert(bytes == null);
881 assert(assertReadyToReadFrom(this, in));
882 setPhase(READ_PHASE);
883 this.in = in;
884 if (optDumpBands) {
885
886 bytesForDump = new ByteArrayOutputStream();
887 this.in = new FilterInputStream(in) {
888 public int read() throws IOException {
889 int ch = in.read();
890 if (ch >= 0) bytesForDump.write(ch);
891 return ch;
892 }
893 public int read(byte b[], int off, int len) throws IOException {
894 int nr = in.read(b, off, len);
895 if (nr >= 0) bytesForDump.write(b, off, nr);
896 return nr;
897 }
898 };
899 }
900 super.readyToDisburse();
901 }
902
903 public OutputStream collectorStream() {
904 assert(phase() == COLLECT_PHASE);
905 assert(bytes != null);
906 return bytes;
907 }
908
909 public InputStream getInputStream() {
910 assert(phase() == DISBURSE_PHASE);
911 assert(in != null);
912 return in;
913 }
914 public int getByte() throws IOException {
915 int b = getInputStream().read();
916 if (b < 0) throw new EOFException();
917 return b;
918 }
919 public void putByte(int b) throws IOException {
920 assert(b == (b & 0xFF));
921 collectorStream().write(b);
922 }
923 public String toString() {
924 return "byte "+super.toString();
925 }
926 }
927
928 class IntBand extends ValueBand {
929
930 public IntBand(String name, Coding regularCoding) {
931 super(name, regularCoding);
932 }
933
934 public void putInt(int x) {
935 assert(phase() == COLLECT_PHASE);
936 addValue(x);
937 }
938
939 public int getInt() {
940 return getValue();
941 }
942
943 public int getIntTotal() {
944 assert(phase() == DISBURSE_PHASE);
945
946 assert(valuesRemainingForDebug() == length());
947 int total = 0;
948 for (int k = length(); k > 0; k--) {
949 total += getInt();
950 }
951 resetForSecondPass();
952 return total;
953 }
954
955 public int getIntCount(int value) {
956 assert(phase() == DISBURSE_PHASE);
957
958 assert(valuesRemainingForDebug() == length());
959 int total = 0;
960 for (int k = length(); k > 0; k--) {
961 if (getInt() == value) {
962 total += 1;
963 }
964 }
965 resetForSecondPass();
966 return total;
967 }
968 }
969
970 static int getIntTotal(int[] values) {
971 int total = 0;
972 for (int i = 0; i < values.length; i++) {
973 total += values[i];
974 }
975 return total;
976 }
977
978 class CPRefBand extends ValueBand {
979 Index index;
980 boolean nullOK;
981
982 public CPRefBand(String name, Coding regularCoding, byte cpTag, boolean nullOK) {
983 super(name, regularCoding);
984 this.nullOK = nullOK;
985 if (cpTag != CONSTANT_None)
986 setBandIndex(this, cpTag);
987 }
988 public CPRefBand(String name, Coding regularCoding, byte cpTag) {
989 this(name, regularCoding, cpTag, false);
990 }
991 public CPRefBand(String name, Coding regularCoding, Object undef) {
992 this(name, regularCoding, CONSTANT_None, false);
993 }
994
995 public void setIndex(Index index) {
996 this.index = index;
997 }
998
999 protected void readDataFrom(InputStream in) throws IOException {
1000 super.readDataFrom(in);
1001 assert(assertValidCPRefs(this));
1002 }
1003
1004
1005 public void putRef(Entry e) {
1006 assert(index != null);
1007 addValue(encodeRefOrNull(e, index));
1008 }
1009 public void putRef(Entry e, Index index) {
1010 assert(this.index == null);
1011 addValue(encodeRefOrNull(e, index));
1012 }
1013 public void putRef(Entry e, byte cptag) {
1014 putRef(e, getCPIndex(cptag));
1015 }
1016
1017 public Entry getRef() {
1018 if (index == null) Utils.log.warning("No index for "+this);
1019 assert(index != null);
1020 return decodeRefOrNull(getValue(), index);
1021 }
1022 public Entry getRef(Index index) {
1023 assert(this.index == null);
1024 return decodeRefOrNull(getValue(), index);
1025 }
1026 public Entry getRef(byte cptag) {
1027 return getRef(getCPIndex(cptag));
1028 }
1029
1030 private int encodeRefOrNull(Entry e, Index index) {
1031 int nonNullCode;
1032 if (e == null) {
1033 nonNullCode = -1;
1034 } else {
1035 nonNullCode = encodeRef(e, index);
1036 }
1037
1038 return (nullOK ? 1 : 0) + nonNullCode;
1039 }
1040 private Entry decodeRefOrNull(int code, Index index) {
1041
1042 int nonNullCode = code - (nullOK ? 1 : 0);
1043 if (nonNullCode == -1) {
1044 return null;
1045 } else {
1046 return decodeRef(nonNullCode, index);
1047 }
1048 }
1049 }
1050
1051
1052
1053 private final List<CPRefBand> allKQBands = new ArrayList<>();
1054 private List<Object[]> needPredefIndex = new ArrayList<>();
1055
1056
1057 int encodeRef(Entry e, Index ix) {
1058 int coding = ix.indexOf(e);
1059 if (verbose > 2)
1060 Utils.log.fine("putRef "+coding+" => "+e);
1061 return coding;
1062 }
1063
1064 Entry decodeRef(int n, Index ix) {
1065 if (n < 0 || n >= ix.size())
1066 Utils.log.warning("decoding bad ref "+n+" in "+ix);
1067 Entry e = ix.getEntry(n);
1068 if (verbose > 2)
1069 Utils.log.fine("getRef "+n+" => "+e);
1070 return e;
1071 }
1072
1073 private CodingChooser codingChooser;
1074 protected CodingChooser getCodingChooser() {
1075 if (codingChooser == null) {
1076 codingChooser = new CodingChooser(effort, basicCodings);
1077 if (codingChooser.stress != null
1078 && this instanceof PackageWriter) {
1079
1080
1081 List<Package.Class> classes = ((PackageWriter)this).pkg.classes;
1082 if (!classes.isEmpty()) {
1083 Package.Class cls = classes.get(0);
1084 codingChooser.addStressSeed(cls.getName().hashCode());
1085 }
1086 }
1087 }
1088 return codingChooser;
1089 }
1090
1091 public CodingMethod chooseCoding(int[] values, int start, int end,
1092 Coding regular, String bandName,
1093 int[] sizes) {
1094 assert(optVaryCodings);
1095 if (effort <= MIN_EFFORT) {
1096 return regular;
1097 }
1098 CodingChooser cc = getCodingChooser();
1099 if (verbose > 1 || cc.verbose > 1) {
1100 Utils.log.fine("--- chooseCoding "+bandName);
1101 }
1102 return cc.choose(values, start, end, regular, sizes);
1103 }
1104
1105 static final byte[] defaultMetaCoding = { _meta_default };
1106 static final byte[] noMetaCoding = {};
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126 protected static int decodeEscapeValue(int X, Coding regularCoding) {
1127
1128
1129
1130
1131 if (regularCoding.B() == 1 || regularCoding.L() == 0)
1132 return -1;
1133 if (regularCoding.S() != 0) {
1134 if (-256 <= X && X <= -1 && regularCoding.min() <= -256) {
1135 int XB = -1-X;
1136 assert(XB >= 0 && XB < 256);
1137 return XB;
1138 }
1139 } else {
1140 int L = regularCoding.L();
1141 if (L <= X && X <= L+255 && regularCoding.max() >= L+255) {
1142 int XB = X-L;
1143 assert(XB >= 0 && XB < 256);
1144 return XB;
1145 }
1146 }
1147 return -1;
1148 }
1149
1150 protected static int encodeEscapeValue(int XB, Coding regularCoding) {
1151 assert(XB >= 0 && XB < 256);
1152 assert(regularCoding.B() > 1 && regularCoding.L() > 0);
1153 int X;
1154 if (regularCoding.S() != 0) {
1155 assert(regularCoding.min() <= -256);
1156 X = -1-XB;
1157 } else {
1158 int L = regularCoding.L();
1159 assert(regularCoding.max() >= L+255);
1160 X = XB+L;
1161 }
1162 assert(decodeEscapeValue(X, regularCoding) == XB)
1163 : (regularCoding+" XB="+XB+" X="+X);
1164 return X;
1165 }
1166
1167 static {
1168 boolean checkXB = false;
1169 assert(checkXB = true);
1170 if (checkXB) {
1171 for (int i = 0; i < basicCodings.length; i++) {
1172 Coding D = basicCodings[i];
1173 if (D == null) continue;
1174 if (D.B() == 1) continue;
1175 if (D.L() == 0) continue;
1176 for (int XB = 0; XB <= 255; XB++) {
1177
1178 encodeEscapeValue(XB, D);
1179 }
1180 }
1181 }
1182 }
1183
1184 class MultiBand extends Band {
1185 MultiBand(String name, Coding regularCoding) {
1186 super(name, regularCoding);
1187 }
1188
1189 public Band init() {
1190 super.init();
1191
1192 setCapacity(0);
1193 if (phase() == EXPECT_PHASE) {
1194
1195 setPhase(READ_PHASE);
1196 setPhase(DISBURSE_PHASE);
1197 }
1198 return this;
1199 }
1200
1201 Band[] bands = new Band[10];
1202 int bandCount = 0;
1203
1204 int size() {
1205 return bandCount;
1206 }
1207 Band get(int i) {
1208 assert(i < bandCount);
1209 return bands[i];
1210 }
1211 Band[] toArray() {
1212 return (Band[]) realloc(bands, bandCount);
1213 }
1214
1215 void add(Band b) {
1216 assert(bandCount == 0 || notePrevForAssert(b, bands[bandCount-1]));
1217 if (bandCount == bands.length) {
1218 bands = (Band[]) realloc(bands);
1219 }
1220 bands[bandCount++] = b;
1221 }
1222
1223 ByteBand newByteBand(String name) {
1224 ByteBand b = new ByteBand(name);
1225 b.init(); add(b);
1226 return b;
1227 }
1228 IntBand newIntBand(String name) {
1229 IntBand b = new IntBand(name, regularCoding);
1230 b.init(); add(b);
1231 return b;
1232 }
1233 IntBand newIntBand(String name, Coding regularCoding) {
1234 IntBand b = new IntBand(name, regularCoding);
1235 b.init(); add(b);
1236 return b;
1237 }
1238 MultiBand newMultiBand(String name, Coding regularCoding) {
1239 MultiBand b = new MultiBand(name, regularCoding);
1240 b.init(); add(b);
1241 return b;
1242 }
1243 CPRefBand newCPRefBand(String name, byte cpTag) {
1244 CPRefBand b = new CPRefBand(name, regularCoding, cpTag);
1245 b.init(); add(b);
1246 return b;
1247 }
1248 CPRefBand newCPRefBand(String name, Coding regularCoding,
1249 byte cpTag) {
1250 CPRefBand b = new CPRefBand(name, regularCoding, cpTag);
1251 b.init(); add(b);
1252 return b;
1253 }
1254 CPRefBand newCPRefBand(String name, Coding regularCoding,
1255 byte cpTag, boolean nullOK) {
1256 CPRefBand b = new CPRefBand(name, regularCoding, cpTag, nullOK);
1257 b.init(); add(b);
1258 return b;
1259 }
1260
1261 int bandCount() { return bandCount; }
1262
1263 private int cap = -1;
1264 public int capacity() { return cap; }
1265 public void setCapacity(int cap) { this.cap = cap; }
1266
1267 public int length() { return 0; }
1268 public int valuesRemainingForDebug() { return 0; }
1269
1270 protected void chooseBandCodings() throws IOException {
1271
1272 for (int i = 0; i < bandCount; i++) {
1273 Band b = bands[i];
1274 b.chooseBandCodings();
1275 }
1276 }
1277
1278 protected long computeOutputSize() {
1279
1280 long sum = 0;
1281 for (int i = 0; i < bandCount; i++) {
1282 Band b = bands[i];
1283 long bsize = b.outputSize();
1284 assert(bsize >= 0) : b;
1285 sum += bsize;
1286 }
1287
1288 return sum;
1289 }
1290
1291 protected void writeDataTo(OutputStream out) throws IOException {
1292 long preCount = 0;
1293 if (outputCounter != null) preCount = outputCounter.getCount();
1294 for (int i = 0; i < bandCount; i++) {
1295 Band b = bands[i];
1296 b.writeTo(out);
1297 if (outputCounter != null) {
1298 long postCount = outputCounter.getCount();
1299 long len = postCount - preCount;
1300 preCount = postCount;
1301 if ((verbose > 0 && len > 0) || verbose > 1) {
1302 Utils.log.info(" ...wrote "+len+" bytes from "+b);
1303 }
1304 }
1305 }
1306 }
1307
1308 protected void readDataFrom(InputStream in) throws IOException {
1309 assert(false);
1310 for (int i = 0; i < bandCount; i++) {
1311 Band b = bands[i];
1312 b.readFrom(in);
1313 if ((verbose > 0 && b.length() > 0) || verbose > 1) {
1314 Utils.log.info(" ...read "+b);
1315 }
1316 }
1317 }
1318
1319 public String toString() {
1320 return "{"+bandCount()+" bands: "+super.toString()+"}";
1321 }
1322 }
1323
1324
1325
1326
1327 private static
1328 class ByteCounter extends FilterOutputStream {
1329
1330
1331 private long count;
1332
1333 public ByteCounter(OutputStream out) {
1334 super(out);
1335 }
1336
1337 public long getCount() { return count; }
1338 public void setCount(long c) { count = c; }
1339
1340 public void write(int b) throws IOException {
1341 count++;
1342 if (out != null) out.write(b);
1343 }
1344 public void write(byte b[], int off, int len) throws IOException {
1345 count += len;
1346 if (out != null) out.write(b, off, len);
1347 }
1348 public String toString() {
1349 return String.valueOf(getCount());
1350 }
1351 }
1352 ByteCounter outputCounter;
1353
1354 void writeAllBandsTo(OutputStream out) throws IOException {
1355
1356 outputCounter = new ByteCounter(out);
1357 out = outputCounter;
1358 all_bands.writeTo(out);
1359 if (verbose > 0) {
1360 long nbytes = outputCounter.getCount();
1361 Utils.log.info("Wrote total of "+nbytes+" bytes.");
1362 assert(nbytes == archiveSize0+archiveSize1);
1363 }
1364 outputCounter = null;
1365 }
1366
1367
1368 protected int archiveOptions;
1369
1370
1371 protected long archiveSize0;
1372 protected long archiveSize1;
1373 protected int archiveNextCount;
1374
1375 static final int AH_LENGTH_0 = 3;
1376 static final int AH_ARCHIVE_SIZE_HI = 0;
1377 static final int AH_ARCHIVE_SIZE_LO = 1;
1378 static final int AH_LENGTH_S = 2;
1379 static final int AH_LENGTH = 26;
1380
1381 static final int AH_FILE_HEADER_LEN = 5;
1382 static final int AH_SPECIAL_FORMAT_LEN = 2;
1383 static final int AH_CP_NUMBER_LEN = 4;
1384 static final int AH_LENGTH_MIN = AH_LENGTH
1385 -(AH_SPECIAL_FORMAT_LEN+AH_FILE_HEADER_LEN+AH_CP_NUMBER_LEN);
1386
1387
1388 static final int AB_FLAGS_HI = 0;
1389 static final int AB_FLAGS_LO = 1;
1390 static final int AB_ATTR_COUNT = 2;
1391 static final int AB_ATTR_INDEXES = 3;
1392 static final int AB_ATTR_CALLS = 4;
1393
1394 static IntBand getAttrBand(MultiBand xxx_attr_bands, int which) {
1395 IntBand b = (IntBand) xxx_attr_bands.get(which);
1396 switch (which) {
1397 case AB_FLAGS_HI:
1398 assert(b.name().endsWith("_flags_hi")); break;
1399 case AB_FLAGS_LO:
1400 assert(b.name().endsWith("_flags_lo")); break;
1401 case AB_ATTR_COUNT:
1402 assert(b.name().endsWith("_attr_count")); break;
1403 case AB_ATTR_INDEXES:
1404 assert(b.name().endsWith("_attr_indexes")); break;
1405 case AB_ATTR_CALLS:
1406 assert(b.name().endsWith("_attr_calls")); break;
1407 default:
1408 assert(false); break;
1409 }
1410 return b;
1411 }
1412
1413 static private final boolean NULL_IS_OK = true;
1414
1415 MultiBand all_bands = (MultiBand) new MultiBand("(package)", UNSIGNED5).init();
1416
1417
1418 ByteBand archive_magic = all_bands.newByteBand("archive_magic");
1419 IntBand archive_header_0 = all_bands.newIntBand("archive_header_0", UNSIGNED5);
1420 IntBand archive_header_S = all_bands.newIntBand("archive_header_S", UNSIGNED5);
1421 IntBand archive_header_1 = all_bands.newIntBand("archive_header_1", UNSIGNED5);
1422 ByteBand band_headers = all_bands.newByteBand("band_headers");
1423
1424
1425 MultiBand cp_bands = all_bands.newMultiBand("(constant_pool)", DELTA5);
1426 IntBand cp_Utf8_prefix = cp_bands.newIntBand("cp_Utf8_prefix");
1427 IntBand cp_Utf8_suffix = cp_bands.newIntBand("cp_Utf8_suffix", UNSIGNED5);
1428 IntBand cp_Utf8_chars = cp_bands.newIntBand("cp_Utf8_chars", CHAR3);
1429 IntBand cp_Utf8_big_suffix = cp_bands.newIntBand("cp_Utf8_big_suffix");
1430 MultiBand cp_Utf8_big_chars = cp_bands.newMultiBand("(cp_Utf8_big_chars)", DELTA5);
1431 IntBand cp_Int = cp_bands.newIntBand("cp_Int", UDELTA5);
1432 IntBand cp_Float = cp_bands.newIntBand("cp_Float", UDELTA5);
1433 IntBand cp_Long_hi = cp_bands.newIntBand("cp_Long_hi", UDELTA5);
1434 IntBand cp_Long_lo = cp_bands.newIntBand("cp_Long_lo");
1435 IntBand cp_Double_hi = cp_bands.newIntBand("cp_Double_hi", UDELTA5);
1436 IntBand cp_Double_lo = cp_bands.newIntBand("cp_Double_lo");
1437 CPRefBand cp_String = cp_bands.newCPRefBand("cp_String", UDELTA5, CONSTANT_Utf8);
1438 CPRefBand cp_Class = cp_bands.newCPRefBand("cp_Class", UDELTA5, CONSTANT_Utf8);
1439 CPRefBand cp_Signature_form = cp_bands.newCPRefBand("cp_Signature_form", CONSTANT_Utf8);
1440 CPRefBand cp_Signature_classes = cp_bands.newCPRefBand("cp_Signature_classes", UDELTA5, CONSTANT_Class);
1441 CPRefBand cp_Descr_name = cp_bands.newCPRefBand("cp_Descr_name", CONSTANT_Utf8);
1442 CPRefBand cp_Descr_type = cp_bands.newCPRefBand("cp_Descr_type", UDELTA5, CONSTANT_Signature);
1443 CPRefBand cp_Field_class = cp_bands.newCPRefBand("cp_Field_class", CONSTANT_Class);
1444 CPRefBand cp_Field_desc = cp_bands.newCPRefBand("cp_Field_desc", UDELTA5, CONSTANT_NameandType);
1445 CPRefBand cp_Method_class = cp_bands.newCPRefBand("cp_Method_class", CONSTANT_Class);
1446 CPRefBand cp_Method_desc = cp_bands.newCPRefBand("cp_Method_desc", UDELTA5, CONSTANT_NameandType);
1447 CPRefBand cp_Imethod_class = cp_bands.newCPRefBand("cp_Imethod_class", CONSTANT_Class);
1448 CPRefBand cp_Imethod_desc = cp_bands.newCPRefBand("cp_Imethod_desc", UDELTA5, CONSTANT_NameandType);
1449
1450
1451 MultiBand attr_definition_bands = all_bands.newMultiBand("(attr_definition_bands)", UNSIGNED5);
1452 ByteBand attr_definition_headers = attr_definition_bands.newByteBand("attr_definition_headers");
1453 CPRefBand attr_definition_name = attr_definition_bands.newCPRefBand("attr_definition_name", CONSTANT_Utf8);
1454 CPRefBand attr_definition_layout = attr_definition_bands.newCPRefBand("attr_definition_layout", CONSTANT_Utf8);
1455
1456
1457 MultiBand ic_bands = all_bands.newMultiBand("(ic_bands)", DELTA5);
1458 CPRefBand ic_this_class = ic_bands.newCPRefBand("ic_this_class", UDELTA5, CONSTANT_Class);
1459 IntBand ic_flags = ic_bands.newIntBand("ic_flags", UNSIGNED5);
1460
1461 CPRefBand ic_outer_class = ic_bands.newCPRefBand("ic_outer_class", DELTA5, CONSTANT_Class, NULL_IS_OK);
1462 CPRefBand ic_name = ic_bands.newCPRefBand("ic_name", DELTA5, CONSTANT_Utf8, NULL_IS_OK);
1463
1464
1465 MultiBand class_bands = all_bands.newMultiBand("(class_bands)", DELTA5);
1466 CPRefBand class_this = class_bands.newCPRefBand("class_this", CONSTANT_Class);
1467 CPRefBand class_super = class_bands.newCPRefBand("class_super", CONSTANT_Class);
1468 IntBand class_interface_count = class_bands.newIntBand("class_interface_count");
1469 CPRefBand class_interface = class_bands.newCPRefBand("class_interface", CONSTANT_Class);
1470
1471
1472 IntBand class_field_count = class_bands.newIntBand("class_field_count");
1473 IntBand class_method_count = class_bands.newIntBand("class_method_count");
1474
1475 CPRefBand field_descr = class_bands.newCPRefBand("field_descr", CONSTANT_NameandType);
1476 MultiBand field_attr_bands = class_bands.newMultiBand("(field_attr_bands)", UNSIGNED5);
1477 IntBand field_flags_hi = field_attr_bands.newIntBand("field_flags_hi");
1478 IntBand field_flags_lo = field_attr_bands.newIntBand("field_flags_lo");
1479 IntBand field_attr_count = field_attr_bands.newIntBand("field_attr_count");
1480 IntBand field_attr_indexes = field_attr_bands.newIntBand("field_attr_indexes");
1481 IntBand field_attr_calls = field_attr_bands.newIntBand("field_attr_calls");
1482
1483
1484 CPRefBand field_ConstantValue_KQ = field_attr_bands.newCPRefBand("field_ConstantValue_KQ", CONSTANT_Literal);
1485 CPRefBand field_Signature_RS = field_attr_bands.newCPRefBand("field_Signature_RS", CONSTANT_Signature);
1486 MultiBand field_metadata_bands = field_attr_bands.newMultiBand("(field_metadata_bands)", UNSIGNED5);
1487
1488 CPRefBand method_descr = class_bands.newCPRefBand("method_descr", MDELTA5, CONSTANT_NameandType);
1489 MultiBand method_attr_bands = class_bands.newMultiBand("(method_attr_bands)", UNSIGNED5);
1490 IntBand method_flags_hi = method_attr_bands.newIntBand("method_flags_hi");
1491 IntBand method_flags_lo = method_attr_bands.newIntBand("method_flags_lo");
1492 IntBand method_attr_count = method_attr_bands.newIntBand("method_attr_count");
1493 IntBand method_attr_indexes = method_attr_bands.newIntBand("method_attr_indexes");
1494 IntBand method_attr_calls = method_attr_bands.newIntBand("method_attr_calls");
1495
1496 IntBand method_Exceptions_N = method_attr_bands.newIntBand("method_Exceptions_N");
1497 CPRefBand method_Exceptions_RC = method_attr_bands.newCPRefBand("method_Exceptions_RC", CONSTANT_Class);
1498 CPRefBand method_Signature_RS = method_attr_bands.newCPRefBand("method_Signature_RS", CONSTANT_Signature);
1499 MultiBand method_metadata_bands = method_attr_bands.newMultiBand("(method_metadata_bands)", UNSIGNED5);
1500
1501 MultiBand class_attr_bands = class_bands.newMultiBand("(class_attr_bands)", UNSIGNED5);
1502 IntBand class_flags_hi = class_attr_bands.newIntBand("class_flags_hi");
1503 IntBand class_flags_lo = class_attr_bands.newIntBand("class_flags_lo");
1504 IntBand class_attr_count = class_attr_bands.newIntBand("class_attr_count");
1505 IntBand class_attr_indexes = class_attr_bands.newIntBand("class_attr_indexes");
1506 IntBand class_attr_calls = class_attr_bands.newIntBand("class_attr_calls");
1507
1508 CPRefBand class_SourceFile_RUN = class_attr_bands.newCPRefBand("class_SourceFile_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
1509 CPRefBand class_EnclosingMethod_RC = class_attr_bands.newCPRefBand("class_EnclosingMethod_RC", CONSTANT_Class);
1510 CPRefBand class_EnclosingMethod_RDN = class_attr_bands.newCPRefBand("class_EnclosingMethod_RDN", UNSIGNED5, CONSTANT_NameandType, NULL_IS_OK);
1511 CPRefBand class_Signature_RS = class_attr_bands.newCPRefBand("class_Signature_RS", CONSTANT_Signature);
1512 MultiBand class_metadata_bands = class_attr_bands.newMultiBand("(class_metadata_bands)", UNSIGNED5);
1513 IntBand class_InnerClasses_N = class_attr_bands.newIntBand("class_InnerClasses_N");
1514 CPRefBand class_InnerClasses_RC = class_attr_bands.newCPRefBand("class_InnerClasses_RC", CONSTANT_Class);
1515 IntBand class_InnerClasses_F = class_attr_bands.newIntBand("class_InnerClasses_F");
1516 CPRefBand class_InnerClasses_outer_RCN = class_attr_bands.newCPRefBand("class_InnerClasses_outer_RCN", UNSIGNED5, CONSTANT_Class, NULL_IS_OK);
1517 CPRefBand class_InnerClasses_name_RUN = class_attr_bands.newCPRefBand("class_InnerClasses_name_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
1518 IntBand class_ClassFile_version_minor_H = class_attr_bands.newIntBand("class_ClassFile_version_minor_H");
1519 IntBand class_ClassFile_version_major_H = class_attr_bands.newIntBand("class_ClassFile_version_major_H");
1520
1521 MultiBand code_bands = class_bands.newMultiBand("(code_bands)", UNSIGNED5);
1522 ByteBand code_headers = code_bands.newByteBand("code_headers");
1523 IntBand code_max_stack = code_bands.newIntBand("code_max_stack", UNSIGNED5);
1524 IntBand code_max_na_locals = code_bands.newIntBand("code_max_na_locals", UNSIGNED5);
1525 IntBand code_handler_count = code_bands.newIntBand("code_handler_count", UNSIGNED5);
1526 IntBand code_handler_start_P = code_bands.newIntBand("code_handler_start_P", BCI5);
1527 IntBand code_handler_end_PO = code_bands.newIntBand("code_handler_end_PO", BRANCH5);
1528 IntBand code_handler_catch_PO = code_bands.newIntBand("code_handler_catch_PO", BRANCH5);
1529 CPRefBand code_handler_class_RCN = code_bands.newCPRefBand("code_handler_class_RCN", UNSIGNED5, CONSTANT_Class, NULL_IS_OK);
1530
1531 MultiBand code_attr_bands = class_bands.newMultiBand("(code_attr_bands)", UNSIGNED5);
1532 IntBand code_flags_hi = code_attr_bands.newIntBand("code_flags_hi");
1533 IntBand code_flags_lo = code_attr_bands.newIntBand("code_flags_lo");
1534 IntBand code_attr_count = code_attr_bands.newIntBand("code_attr_count");
1535 IntBand code_attr_indexes = code_attr_bands.newIntBand("code_attr_indexes");
1536 IntBand code_attr_calls = code_attr_bands.newIntBand("code_attr_calls");
1537
1538 MultiBand stackmap_bands = code_attr_bands.newMultiBand("StackMapTable_bands", UNSIGNED5);
1539 IntBand code_StackMapTable_N = stackmap_bands.newIntBand("code_StackMapTable_N");
1540 IntBand code_StackMapTable_frame_T = stackmap_bands.newIntBand("code_StackMapTable_frame_T",BYTE1);
1541 IntBand code_StackMapTable_local_N = stackmap_bands.newIntBand("code_StackMapTable_local_N");
1542 IntBand code_StackMapTable_stack_N = stackmap_bands.newIntBand("code_StackMapTable_stack_N");
1543 IntBand code_StackMapTable_offset = stackmap_bands.newIntBand("code_StackMapTable_offset", UNSIGNED5);
1544 IntBand code_StackMapTable_T = stackmap_bands.newIntBand("code_StackMapTable_T", BYTE1);
1545 CPRefBand code_StackMapTable_RC = stackmap_bands.newCPRefBand("code_StackMapTable_RC", CONSTANT_Class);
1546 IntBand code_StackMapTable_P = stackmap_bands.newIntBand("code_StackMapTable_P", BCI5);
1547
1548
1549 IntBand code_LineNumberTable_N = code_attr_bands.newIntBand("code_LineNumberTable_N");
1550 IntBand code_LineNumberTable_bci_P = code_attr_bands.newIntBand("code_LineNumberTable_bci_P", BCI5);
1551 IntBand code_LineNumberTable_line = code_attr_bands.newIntBand("code_LineNumberTable_line");
1552
1553
1554 IntBand code_LocalVariableTable_N = code_attr_bands.newIntBand("code_LocalVariableTable_N");
1555 IntBand code_LocalVariableTable_bci_P = code_attr_bands.newIntBand("code_LocalVariableTable_bci_P", BCI5);
1556 IntBand code_LocalVariableTable_span_O = code_attr_bands.newIntBand("code_LocalVariableTable_span_O", BRANCH5);
1557 CPRefBand code_LocalVariableTable_name_RU = code_attr_bands.newCPRefBand("code_LocalVariableTable_name_RU", CONSTANT_Utf8);
1558 CPRefBand code_LocalVariableTable_type_RS = code_attr_bands.newCPRefBand("code_LocalVariableTable_type_RS", CONSTANT_Signature);
1559 IntBand code_LocalVariableTable_slot = code_attr_bands.newIntBand("code_LocalVariableTable_slot");
1560 IntBand code_LocalVariableTypeTable_N = code_attr_bands.newIntBand("code_LocalVariableTypeTable_N");
1561 IntBand code_LocalVariableTypeTable_bci_P = code_attr_bands.newIntBand("code_LocalVariableTypeTable_bci_P", BCI5);
1562 IntBand code_LocalVariableTypeTable_span_O = code_attr_bands.newIntBand("code_LocalVariableTypeTable_span_O", BRANCH5);
1563 CPRefBand code_LocalVariableTypeTable_name_RU = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_name_RU", CONSTANT_Utf8);
1564 CPRefBand code_LocalVariableTypeTable_type_RS = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_type_RS", CONSTANT_Signature);
1565 IntBand code_LocalVariableTypeTable_slot = code_attr_bands.newIntBand("code_LocalVariableTypeTable_slot");
1566
1567
1568 MultiBand bc_bands = all_bands.newMultiBand("(byte_codes)", UNSIGNED5);
1569 ByteBand bc_codes = bc_bands.newByteBand("bc_codes");
1570
1571
1572 IntBand bc_case_count = bc_bands.newIntBand("bc_case_count");
1573 IntBand bc_case_value = bc_bands.newIntBand("bc_case_value", DELTA5);
1574 ByteBand bc_byte = bc_bands.newByteBand("bc_byte");
1575 IntBand bc_short = bc_bands.newIntBand("bc_short", DELTA5);
1576 IntBand bc_local = bc_bands.newIntBand("bc_local");
1577 IntBand bc_label = bc_bands.newIntBand("bc_label", BRANCH5);
1578
1579
1580
1581
1582
1583 CPRefBand bc_intref = bc_bands.newCPRefBand("bc_intref", DELTA5, CONSTANT_Integer);
1584 CPRefBand bc_floatref = bc_bands.newCPRefBand("bc_floatref", DELTA5, CONSTANT_Float);
1585 CPRefBand bc_longref = bc_bands.newCPRefBand("bc_longref", DELTA5, CONSTANT_Long);
1586 CPRefBand bc_doubleref = bc_bands.newCPRefBand("bc_doubleref", DELTA5, CONSTANT_Double);
1587 CPRefBand bc_stringref = bc_bands.newCPRefBand("bc_stringref", DELTA5, CONSTANT_String);
1588
1589
1590 CPRefBand bc_classref = bc_bands.newCPRefBand("bc_classref", UNSIGNED5, CONSTANT_Class, NULL_IS_OK);
1591 CPRefBand bc_fieldref = bc_bands.newCPRefBand("bc_fieldref", DELTA5, CONSTANT_Fieldref);
1592 CPRefBand bc_methodref = bc_bands.newCPRefBand("bc_methodref", CONSTANT_Methodref);
1593 CPRefBand bc_imethodref = bc_bands.newCPRefBand("bc_imethodref", DELTA5, CONSTANT_InterfaceMethodref);
1594
1595
1596 CPRefBand bc_thisfield = bc_bands.newCPRefBand("bc_thisfield", CONSTANT_None);
1597 CPRefBand bc_superfield = bc_bands.newCPRefBand("bc_superfield", CONSTANT_None);
1598 CPRefBand bc_thismethod = bc_bands.newCPRefBand("bc_thismethod", CONSTANT_None);
1599 CPRefBand bc_supermethod = bc_bands.newCPRefBand("bc_supermethod", CONSTANT_None);
1600
1601 IntBand bc_initref = bc_bands.newIntBand("bc_initref");
1602
1603 CPRefBand bc_escref = bc_bands.newCPRefBand("bc_escref", CONSTANT_All);
1604 IntBand bc_escrefsize = bc_bands.newIntBand("bc_escrefsize");
1605 IntBand bc_escsize = bc_bands.newIntBand("bc_escsize");
1606 ByteBand bc_escbyte = bc_bands.newByteBand("bc_escbyte");
1607
1608
1609 MultiBand file_bands = all_bands.newMultiBand("(file_bands)", UNSIGNED5);
1610 CPRefBand file_name = file_bands.newCPRefBand("file_name", CONSTANT_Utf8);
1611 IntBand file_size_hi = file_bands.newIntBand("file_size_hi");
1612 IntBand file_size_lo = file_bands.newIntBand("file_size_lo");
1613 IntBand file_modtime = file_bands.newIntBand("file_modtime", DELTA5);
1614 IntBand file_options = file_bands.newIntBand("file_options");
1615 ByteBand file_bits = file_bands.newByteBand("file_bits");
1616
1617
1618
1619
1620 protected void setBandIndexes() {
1621
1622 for (Object[] need : needPredefIndex) {
1623 CPRefBand b = (CPRefBand) need[0];
1624 Byte which = (Byte) need[1];
1625 b.setIndex(getCPIndex(which.byteValue()));
1626 }
1627 needPredefIndex = null;
1628
1629 if (verbose > 3) {
1630 printCDecl(all_bands);
1631 }
1632 }
1633
1634 protected void setBandIndex(CPRefBand b, byte which) {
1635 Object[] need = { b, Byte.valueOf(which) };
1636 if (which == CONSTANT_Literal) {
1637
1638 allKQBands.add(b);
1639 } else if (needPredefIndex != null) {
1640 needPredefIndex.add(need);
1641 } else {
1642
1643 b.setIndex(getCPIndex(which));
1644 }
1645 }
1646
1647 protected void setConstantValueIndex(Field f) {
1648 Index ix = null;
1649 if (f != null) {
1650 byte tag = f.getLiteralTag();
1651 ix = getCPIndex(tag);
1652 if (verbose > 2)
1653 Utils.log.fine("setConstantValueIndex "+f+" "+ConstantPool.tagName(tag)+" => "+ix);
1654 assert(ix != null);
1655 }
1656
1657 for (CPRefBand xxx_KQ : allKQBands) {
1658 xxx_KQ.setIndex(ix);
1659 }
1660 }
1661
1662
1663 protected MultiBand[] metadataBands = new MultiBand[ATTR_CONTEXT_LIMIT];
1664 {
1665 metadataBands[ATTR_CONTEXT_CLASS] = class_metadata_bands;
1666 metadataBands[ATTR_CONTEXT_FIELD] = field_metadata_bands;
1667 metadataBands[ATTR_CONTEXT_METHOD] = method_metadata_bands;
1668 }
1669
1670
1671 public static final int ADH_CONTEXT_MASK = 0x3;
1672 public static final int ADH_BIT_SHIFT = 0x2;
1673 public static final int ADH_BIT_IS_LSB = 1;
1674 public static final int ATTR_INDEX_OVERFLOW = -1;
1675
1676 public int[] attrIndexLimit = new int[ATTR_CONTEXT_LIMIT];
1677
1678
1679
1680 protected long[] attrFlagMask = new long[ATTR_CONTEXT_LIMIT];
1681
1682 protected long[] attrDefSeen = new long[ATTR_CONTEXT_LIMIT];
1683
1684
1685 protected int[] attrOverflowMask = new int[ATTR_CONTEXT_LIMIT];
1686 protected int attrClassFileVersionMask;
1687
1688
1689 protected Map<Attribute.Layout, Band[]> attrBandTable = new HashMap<>();
1690
1691
1692 protected final Attribute.Layout attrCodeEmpty;
1693 protected final Attribute.Layout attrInnerClassesEmpty;
1694 protected final Attribute.Layout attrClassFileVersion;
1695 protected final Attribute.Layout attrConstantValue;
1696
1697
1698 Map<Attribute.Layout, Integer> attrIndexTable = new HashMap<>();
1699
1700
1701 protected List<List<Attribute.Layout>> attrDefs =
1702 new FixedList<>(ATTR_CONTEXT_LIMIT);
1703 {
1704 for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1705 assert(attrIndexLimit[i] == 0);
1706 attrIndexLimit[i] = 32;
1707 attrDefs.set(i, new ArrayList<Attribute.Layout>(Collections.nCopies(
1708 attrIndexLimit[i], (Attribute.Layout)null)));
1709
1710 }
1711
1712
1713 attrInnerClassesEmpty =
1714 predefineAttribute(CLASS_ATTR_InnerClasses, ATTR_CONTEXT_CLASS, null,
1715 "InnerClasses", "");
1716 assert(attrInnerClassesEmpty == Package.attrInnerClassesEmpty);
1717 predefineAttribute(CLASS_ATTR_SourceFile, ATTR_CONTEXT_CLASS,
1718 new Band[] { class_SourceFile_RUN },
1719 "SourceFile", "RUNH");
1720 predefineAttribute(CLASS_ATTR_EnclosingMethod, ATTR_CONTEXT_CLASS,
1721 new Band[] {
1722 class_EnclosingMethod_RC,
1723 class_EnclosingMethod_RDN
1724 },
1725 "EnclosingMethod", "RCHRDNH");
1726 attrClassFileVersion =
1727 predefineAttribute(CLASS_ATTR_ClassFile_version, ATTR_CONTEXT_CLASS,
1728 new Band[] {
1729 class_ClassFile_version_minor_H,
1730 class_ClassFile_version_major_H
1731 },
1732 ".ClassFile.version", "HH");
1733 predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_CLASS,
1734 new Band[] { class_Signature_RS },
1735 "Signature", "RSH");
1736 predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_CLASS, null,
1737 "Deprecated", "");
1738
1739
1740 predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CLASS, null,
1741 ".Overflow", "");
1742 attrConstantValue =
1743 predefineAttribute(FIELD_ATTR_ConstantValue, ATTR_CONTEXT_FIELD,
1744 new Band[] { field_ConstantValue_KQ },
1745 "ConstantValue", "KQH");
1746 predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_FIELD,
1747 new Band[] { field_Signature_RS },
1748 "Signature", "RSH");
1749 predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_FIELD, null,
1750 "Deprecated", "");
1751
1752
1753 predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_FIELD, null,
1754 ".Overflow", "");
1755 attrCodeEmpty =
1756 predefineAttribute(METHOD_ATTR_Code, ATTR_CONTEXT_METHOD, null,
1757 "Code", "");
1758 predefineAttribute(METHOD_ATTR_Exceptions, ATTR_CONTEXT_METHOD,
1759 new Band[] {
1760 method_Exceptions_N,
1761 method_Exceptions_RC
1762 },
1763 "Exceptions", "NH[RCH]");
1764 assert(attrCodeEmpty == Package.attrCodeEmpty);
1765 predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_METHOD,
1766 new Band[] { method_Signature_RS },
1767 "Signature", "RSH");
1768 predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_METHOD, null,
1769 "Deprecated", "");
1770
1771
1772 predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_METHOD, null,
1773 ".Overflow", "");
1774
1775 for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
1776 MultiBand xxx_metadata_bands = metadataBands[ctype];
1777 if (xxx_metadata_bands == null)
1778 continue;
1779
1780
1781
1782 predefineAttribute(X_ATTR_RuntimeVisibleAnnotations,
1783 ATTR_CONTEXT_NAME[ctype]+"_RVA_",
1784 xxx_metadata_bands,
1785 Attribute.lookup(null, ctype,
1786 "RuntimeVisibleAnnotations"));
1787 predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations,
1788 ATTR_CONTEXT_NAME[ctype]+"_RIA_",
1789 xxx_metadata_bands,
1790 Attribute.lookup(null, ctype,
1791 "RuntimeInvisibleAnnotations"));
1792 if (ctype != ATTR_CONTEXT_METHOD)
1793 continue;
1794
1795 predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
1796 "method_RVPA_", xxx_metadata_bands,
1797 Attribute.lookup(null, ctype,
1798 "RuntimeVisibleParameterAnnotations"));
1799 predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
1800 "method_RIPA_", xxx_metadata_bands,
1801 Attribute.lookup(null, ctype,
1802 "RuntimeInvisibleParameterAnnotations"));
1803 predefineAttribute(METHOD_ATTR_AnnotationDefault,
1804 "method_AD_", xxx_metadata_bands,
1805 Attribute.lookup(null, ctype,
1806 "AnnotationDefault"));
1807 }
1808
1809
1810 Attribute.Layout stackMapDef = Attribute.lookup(null, ATTR_CONTEXT_CODE, "StackMapTable").layout();
1811 predefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE,
1812 stackmap_bands.toArray(),
1813 stackMapDef.name(), stackMapDef.layout());
1814
1815 predefineAttribute(CODE_ATTR_LineNumberTable, ATTR_CONTEXT_CODE,
1816 new Band[] {
1817 code_LineNumberTable_N,
1818 code_LineNumberTable_bci_P,
1819 code_LineNumberTable_line
1820 },
1821 "LineNumberTable", "NH[PHH]");
1822 predefineAttribute(CODE_ATTR_LocalVariableTable, ATTR_CONTEXT_CODE,
1823 new Band[] {
1824 code_LocalVariableTable_N,
1825 code_LocalVariableTable_bci_P,
1826 code_LocalVariableTable_span_O,
1827 code_LocalVariableTable_name_RU,
1828 code_LocalVariableTable_type_RS,
1829 code_LocalVariableTable_slot
1830 },
1831 "LocalVariableTable", "NH[PHOHRUHRSHH]");
1832 predefineAttribute(CODE_ATTR_LocalVariableTypeTable, ATTR_CONTEXT_CODE,
1833 new Band[] {
1834 code_LocalVariableTypeTable_N,
1835 code_LocalVariableTypeTable_bci_P,
1836 code_LocalVariableTypeTable_span_O,
1837 code_LocalVariableTypeTable_name_RU,
1838 code_LocalVariableTypeTable_type_RS,
1839 code_LocalVariableTypeTable_slot
1840 },
1841 "LocalVariableTypeTable", "NH[PHOHRUHRSHH]");
1842 predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CODE, null,
1843 ".Overflow", "");
1844
1845
1846
1847 for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1848 attrDefSeen[i] = 0;
1849 }
1850
1851
1852 for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1853 attrOverflowMask[i] = (1<<X_ATTR_OVERFLOW);
1854 attrIndexLimit[i] = 0;
1855 }
1856 attrClassFileVersionMask = (1<<CLASS_ATTR_ClassFile_version);
1857 }
1858
1859 private void adjustToMajver() {
1860 if (getPackageMajver() < JAVA6_PACKAGE_MAJOR_VERSION) {
1861 if (verbose > 0) Utils.log.fine("Legacy package version");
1862
1863 undefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE);
1864 }
1865 }
1866
1867 protected void initAttrIndexLimit() {
1868 for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1869 assert(attrIndexLimit[i] == 0);
1870 attrIndexLimit[i] = (haveFlagsHi(i)? 63: 32);
1871 List<Attribute.Layout> defList = attrDefs.get(i);
1872 assert(defList.size() == 32);
1873 int addMore = attrIndexLimit[i] - defList.size();
1874 defList.addAll(Collections.nCopies(addMore, (Attribute.Layout) null));
1875 }
1876 }
1877
1878 protected boolean haveFlagsHi(int ctype) {
1879 int mask = 1<<(LG_AO_HAVE_XXX_FLAGS_HI+ctype);
1880 switch (ctype) {
1881 case ATTR_CONTEXT_CLASS:
1882 assert(mask == AO_HAVE_CLASS_FLAGS_HI); break;
1883 case ATTR_CONTEXT_FIELD:
1884 assert(mask == AO_HAVE_FIELD_FLAGS_HI); break;
1885 case ATTR_CONTEXT_METHOD:
1886 assert(mask == AO_HAVE_METHOD_FLAGS_HI); break;
1887 case ATTR_CONTEXT_CODE:
1888 assert(mask == AO_HAVE_CODE_FLAGS_HI); break;
1889 default:
1890 assert(false);
1891 }
1892 return testBit(archiveOptions, mask);
1893 }
1894
1895 protected List getPredefinedAttrs(int ctype) {
1896 assert(attrIndexLimit[ctype] != 0);
1897 List<Attribute.Layout> res = new ArrayList<>(attrIndexLimit[ctype]);
1898
1899 for (int ai = 0; ai < attrIndexLimit[ctype]; ai++) {
1900 if (testBit(attrDefSeen[ctype], 1L<<ai)) continue;
1901 Attribute.Layout def = attrDefs.get(ctype).get(ai);
1902 if (def == null) continue;
1903 assert(isPredefinedAttr(ctype, ai));
1904 res.add(def);
1905 }
1906 return res;
1907 }
1908
1909 protected boolean isPredefinedAttr(int ctype, int ai) {
1910 assert(attrIndexLimit[ctype] != 0);
1911
1912 if (ai >= attrIndexLimit[ctype]) return false;
1913
1914 if (testBit(attrDefSeen[ctype], 1L<<ai)) return false;
1915 return (attrDefs.get(ctype).get(ai) != null);
1916 }
1917
1918 protected void adjustSpecialAttrMasks() {
1919
1920 attrClassFileVersionMask &= ~ attrDefSeen[ATTR_CONTEXT_CLASS];
1921
1922 for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1923 attrOverflowMask[i] &= ~ attrDefSeen[i];
1924 }
1925 }
1926
1927 protected Attribute makeClassFileVersionAttr(int minver, int majver) {
1928 byte[] bytes = {
1929 (byte)(minver >> 8), (byte)minver,
1930 (byte)(majver >> 8), (byte)majver
1931 };
1932 return attrClassFileVersion.addContent(bytes);
1933 }
1934
1935 protected short[] parseClassFileVersionAttr(Attribute attr) {
1936 assert(attr.layout() == attrClassFileVersion);
1937 assert(attr.size() == 4);
1938 byte[] bytes = attr.bytes();
1939 int minver = ((bytes[0] & 0xFF) << 8) | (bytes[1] & 0xFF);
1940 int majver = ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF);
1941 return new short[]{ (short) minver, (short) majver };
1942 }
1943
1944 private boolean assertBandOKForElems(Band[] ab, Attribute.Layout.Element[] elems) {
1945 for (int i = 0; i < elems.length; i++) {
1946 assert(assertBandOKForElem(ab, elems[i]));
1947 }
1948 return true;
1949 }
1950 private boolean assertBandOKForElem(Band[] ab, Attribute.Layout.Element e) {
1951 Band b = null;
1952 if (e.bandIndex != Attribute.NO_BAND_INDEX)
1953 b = ab[e.bandIndex];
1954 Coding rc = UNSIGNED5;
1955 boolean wantIntBand = true;
1956 switch (e.kind) {
1957 case Attribute.EK_INT:
1958 if (e.flagTest(Attribute.EF_SIGN)) {
1959 rc = SIGNED5;
1960 } else if (e.len == 1) {
1961 rc = BYTE1;
1962 }
1963 break;
1964 case Attribute.EK_BCI:
1965 if (!e.flagTest(Attribute.EF_DELTA)) {
1966 rc = BCI5;
1967 } else {
1968 rc = BRANCH5;
1969 }
1970 break;
1971 case Attribute.EK_BCO:
1972 rc = BRANCH5;
1973 break;
1974 case Attribute.EK_FLAG:
1975 if (e.len == 1) rc = BYTE1;
1976 break;
1977 case Attribute.EK_REPL:
1978 if (e.len == 1) rc = BYTE1;
1979 assertBandOKForElems(ab, e.body);
1980 break;
1981 case Attribute.EK_UN:
1982 if (e.flagTest(Attribute.EF_SIGN)) {
1983 rc = SIGNED5;
1984 } else if (e.len == 1) {
1985 rc = BYTE1;
1986 }
1987 assertBandOKForElems(ab, e.body);
1988 break;
1989 case Attribute.EK_CASE:
1990 assert(b == null);
1991 assertBandOKForElems(ab, e.body);
1992 return true;
1993 case Attribute.EK_CALL:
1994 assert(b == null);
1995 return true;
1996 case Attribute.EK_CBLE:
1997 assert(b == null);
1998 assertBandOKForElems(ab, e.body);
1999 return true;
2000 case Attribute.EK_REF:
2001 wantIntBand = false;
2002 assert(b instanceof CPRefBand);
2003 assert(((CPRefBand)b).nullOK == e.flagTest(Attribute.EF_NULL));
2004 break;
2005 default: assert(false);
2006 }
2007 assert(b.regularCoding == rc)
2008 : (e+" // "+b);
2009 if (wantIntBand)
2010 assert(b instanceof IntBand);
2011 return true;
2012 }
2013
2014 private
2015 Attribute.Layout predefineAttribute(int index, int ctype, Band[] ab,
2016 String name, String layout) {
2017
2018 Attribute.Layout def = Attribute.find(ctype, name, layout).layout();
2019
2020 if (index >= 0) {
2021 setAttributeLayoutIndex(def, index);
2022 }
2023 if (ab == null) {
2024 ab = new Band[0];
2025 }
2026 assert(attrBandTable.get(def) == null);
2027 attrBandTable.put(def, ab);
2028 assert(def.bandCount == ab.length)
2029 : (def+" // "+Arrays.asList(ab));
2030
2031 assert(assertBandOKForElems(ab, def.elems));
2032 return def;
2033 }
2034
2035
2036 private
2037 Attribute.Layout predefineAttribute(int index,
2038 String bandPrefix, MultiBand addHere,
2039 Attribute attr) {
2040
2041 Attribute.Layout def = attr.layout();
2042 int ctype = def.ctype();
2043 return predefineAttribute(index, ctype,
2044 makeNewAttributeBands(bandPrefix, def,
2045 addHere),
2046 def.name(), def.layout());
2047 }
2048
2049 private
2050 void undefineAttribute(int index, int ctype) {
2051 if (verbose > 1) {
2052 System.out.println("Removing predefined "+ATTR_CONTEXT_NAME[ctype]+
2053 " attribute on bit "+index);
2054 }
2055 List<Attribute.Layout> defList = attrDefs.get(ctype);
2056 Attribute.Layout def = defList.get(index);
2057 assert(def != null);
2058 defList.set(index, null);
2059 attrIndexTable.put(def, null);
2060
2061 assert(index < 64);
2062 attrDefSeen[ctype] &= ~(1L<<index);
2063 attrFlagMask[ctype] &= ~(1L<<index);
2064 Band[] ab = attrBandTable.get(def);
2065 for (int j = 0; j < ab.length; j++) {
2066 ab[j].doneWithUnusedBand();
2067 }
2068 }
2069
2070
2071 protected MultiBand[] attrBands = new MultiBand[ATTR_CONTEXT_LIMIT];
2072 {
2073 attrBands[ATTR_CONTEXT_CLASS] = class_attr_bands;
2074 attrBands[ATTR_CONTEXT_FIELD] = field_attr_bands;
2075 attrBands[ATTR_CONTEXT_METHOD] = method_attr_bands;
2076 attrBands[ATTR_CONTEXT_CODE] = code_attr_bands;
2077 }
2078
2079
2080 void makeNewAttributeBands() {
2081
2082 adjustSpecialAttrMasks();
2083
2084 for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
2085 String cname = ATTR_CONTEXT_NAME[ctype];
2086 MultiBand xxx_attr_bands = attrBands[ctype];
2087 long defSeen = attrDefSeen[ctype];
2088
2089 assert((defSeen & ~attrFlagMask[ctype]) == 0);
2090 for (int i = 0; i < attrDefs.get(ctype).size(); i++) {
2091 Attribute.Layout def = attrDefs.get(ctype).get(i);
2092 if (def == null) continue;
2093 if (def.bandCount == 0) continue;
2094 if (i < attrIndexLimit[ctype] && !testBit(defSeen, 1L<<i)) {
2095
2096 assert(attrBandTable.get(def) != null);
2097 continue;
2098 }
2099 int base = xxx_attr_bands.size();
2100 String pfx = cname+"_"+def.name()+"_";
2101 if (verbose > 1)
2102 Utils.log.fine("Making new bands for "+def);
2103 Band[] newAB = makeNewAttributeBands(pfx, def,
2104 xxx_attr_bands);
2105 assert(newAB.length == def.bandCount);
2106 Band[] prevAB = attrBandTable.put(def, newAB);
2107 if (prevAB != null) {
2108
2109 for (int j = 0; j < prevAB.length; j++) {
2110 prevAB[j].doneWithUnusedBand();
2111 }
2112 }
2113 }
2114 }
2115
2116 }
2117 private
2118 Band[] makeNewAttributeBands(String pfx, Attribute.Layout def,
2119 MultiBand addHere) {
2120 int base = addHere.size();
2121 makeNewAttributeBands(pfx, def.elems, addHere);
2122 int nb = addHere.size() - base;
2123 Band[] newAB = new Band[nb];
2124 for (int i = 0; i < nb; i++) {
2125 newAB[i] = addHere.get(base+i);
2126 }
2127 return newAB;
2128 }
2129
2130 private
2131 void makeNewAttributeBands(String pfx, Attribute.Layout.Element[] elems,
2132 MultiBand ab) {
2133 for (int i = 0; i < elems.length; i++) {
2134 Attribute.Layout.Element e = elems[i];
2135 String name = pfx+ab.size()+"_"+e.layout;
2136 {
2137 int tem;
2138 if ((tem = name.indexOf('[')) > 0)
2139 name = name.substring(0, tem);
2140 if ((tem = name.indexOf('(')) > 0)
2141 name = name.substring(0, tem);
2142 if (name.endsWith("H"))
2143 name = name.substring(0, name.length()-1);
2144 }
2145 Band nb;
2146 switch (e.kind) {
2147 case Attribute.EK_INT:
2148 nb = newElemBand(e, name, ab);
2149 break;
2150 case Attribute.EK_BCI:
2151 if (!e.flagTest(Attribute.EF_DELTA)) {
2152
2153 nb = ab.newIntBand(name, BCI5);
2154 } else {
2155
2156 nb = ab.newIntBand(name, BRANCH5);
2157 }
2158
2159 break;
2160 case Attribute.EK_BCO:
2161
2162 nb = ab.newIntBand(name, BRANCH5);
2163
2164 break;
2165 case Attribute.EK_FLAG:
2166 assert(!e.flagTest(Attribute.EF_SIGN));
2167 nb = newElemBand(e, name, ab);
2168 break;
2169 case Attribute.EK_REPL:
2170 assert(!e.flagTest(Attribute.EF_SIGN));
2171 nb = newElemBand(e, name, ab);
2172 makeNewAttributeBands(pfx, e.body, ab);
2173 break;
2174 case Attribute.EK_UN:
2175 nb = newElemBand(e, name, ab);
2176 makeNewAttributeBands(pfx, e.body, ab);
2177 break;
2178 case Attribute.EK_CASE:
2179 if (!e.flagTest(Attribute.EF_BACK)) {
2180
2181 makeNewAttributeBands(pfx, e.body, ab);
2182 }
2183 continue;
2184 case Attribute.EK_REF:
2185 byte refKind = e.refKind;
2186 boolean nullOK = e.flagTest(Attribute.EF_NULL);
2187 nb = ab.newCPRefBand(name, UNSIGNED5, refKind, nullOK);
2188
2189 break;
2190 case Attribute.EK_CALL:
2191 continue;
2192 case Attribute.EK_CBLE:
2193 makeNewAttributeBands(pfx, e.body, ab);
2194 continue;
2195 default: assert(false); continue;
2196 }
2197 if (verbose > 1) {
2198 Utils.log.fine("New attribute band "+nb);
2199 }
2200 }
2201 }
2202 private
2203 Band newElemBand(Attribute.Layout.Element e, String name, MultiBand ab) {
2204 if (e.flagTest(Attribute.EF_SIGN)) {
2205 return ab.newIntBand(name, SIGNED5);
2206 } else if (e.len == 1) {
2207 return ab.newIntBand(name, BYTE1);
2208 } else {
2209 return ab.newIntBand(name, UNSIGNED5);
2210 }
2211 }
2212
2213 protected int setAttributeLayoutIndex(Attribute.Layout def, int index) {
2214 int ctype = def.ctype;
2215 assert(ATTR_INDEX_OVERFLOW <= index && index < attrIndexLimit[ctype]);
2216 List<Attribute.Layout> defList = attrDefs.get(ctype);
2217 if (index == ATTR_INDEX_OVERFLOW) {
2218
2219 index = defList.size();
2220 defList.add(def);
2221 if (verbose > 0)
2222 Utils.log.info("Adding new attribute at "+def +": "+index);
2223 attrIndexTable.put(def, index);
2224 return index;
2225 }
2226
2227
2228 if (testBit(attrDefSeen[ctype], 1L<<index)) {
2229 throw new RuntimeException("Multiple explicit definition at "+index+": "+def);
2230 }
2231 attrDefSeen[ctype] |= (1L<<index);
2232
2233
2234 assert(0 <= index && index < attrIndexLimit[ctype]);
2235 if (verbose > (attrClassFileVersionMask == 0? 2:0))
2236 Utils.log.fine("Fixing new attribute at "+index
2237 +": "+def
2238 +(defList.get(index) == null? "":
2239 "; replacing "+defList.get(index)));
2240 attrFlagMask[ctype] |= (1L<<index);
2241
2242 attrIndexTable.put(defList.get(index), null);
2243 defList.set(index, def);
2244 attrIndexTable.put(def, index);
2245 return index;
2246 }
2247
2248
2249 private static final int[][] shortCodeLimits = {
2250 { 12, 12 },
2251 { 8, 8 },
2252 { 7, 7 },
2253 };
2254 public final int shortCodeHeader_h_limit = shortCodeLimits.length;
2255
2256
2257 static int shortCodeHeader(Code code) {
2258 int s = code.max_stack;
2259 int l0 = code.max_locals;
2260 int h = code.handler_class.length;
2261 if (h >= shortCodeLimits.length) return LONG_CODE_HEADER;
2262 int siglen = code.getMethod().getArgumentSize();
2263 assert(l0 >= siglen);
2264 if (l0 < siglen) return LONG_CODE_HEADER;
2265 int l1 = l0 - siglen;
2266 int lims = shortCodeLimits[h][0];
2267 int liml = shortCodeLimits[h][1];
2268 if (s >= lims || l1 >= liml) return LONG_CODE_HEADER;
2269 int sc = shortCodeHeader_h_base(h);
2270 sc += s + lims*l1;
2271 if (sc > 255) return LONG_CODE_HEADER;
2272 assert(shortCodeHeader_max_stack(sc) == s);
2273 assert(shortCodeHeader_max_na_locals(sc) == l1);
2274 assert(shortCodeHeader_handler_count(sc) == h);
2275 return sc;
2276 }
2277
2278 static final int LONG_CODE_HEADER = 0;
2279 static int shortCodeHeader_handler_count(int sc) {
2280 assert(sc > 0 && sc <= 255);
2281 for (int h = 0; ; h++) {
2282 if (sc < shortCodeHeader_h_base(h+1))
2283 return h;
2284 }
2285 }
2286 static int shortCodeHeader_max_stack(int sc) {
2287 int h = shortCodeHeader_handler_count(sc);
2288 int lims = shortCodeLimits[h][0];
2289 return (sc - shortCodeHeader_h_base(h)) % lims;
2290 }
2291 static int shortCodeHeader_max_na_locals(int sc) {
2292 int h = shortCodeHeader_handler_count(sc);
2293 int lims = shortCodeLimits[h][0];
2294 return (sc - shortCodeHeader_h_base(h)) / lims;
2295 }
2296
2297 private static int shortCodeHeader_h_base(int h) {
2298 assert(h <= shortCodeLimits.length);
2299 int sc = 1;
2300 for (int h0 = 0; h0 < h; h0++) {
2301 int lims = shortCodeLimits[h0][0];
2302 int liml = shortCodeLimits[h0][1];
2303 sc += lims * liml;
2304 }
2305 return sc;
2306 }
2307
2308
2309 protected void putLabel(IntBand bc_label, Code c, int pc, int targetPC) {
2310 bc_label.putInt(c.encodeBCI(targetPC) - c.encodeBCI(pc));
2311 }
2312 protected int getLabel(IntBand bc_label, Code c, int pc) {
2313 return c.decodeBCI(bc_label.getInt() + c.encodeBCI(pc));
2314 }
2315
2316 protected CPRefBand getCPRefOpBand(int bc) {
2317 switch (Instruction.getCPRefOpTag(bc)) {
2318 case CONSTANT_Class:
2319 return bc_classref;
2320 case CONSTANT_Fieldref:
2321 return bc_fieldref;
2322 case CONSTANT_Methodref:
2323 return bc_methodref;
2324 case CONSTANT_InterfaceMethodref:
2325 return bc_imethodref;
2326 case CONSTANT_Literal:
2327 switch (bc) {
2328 case _ildc: case _ildc_w:
2329 return bc_intref;
2330 case _fldc: case _fldc_w:
2331 return bc_floatref;
2332 case _lldc2_w:
2333 return bc_longref;
2334 case _dldc2_w:
2335 return bc_doubleref;
2336 case _aldc: case _aldc_w:
2337 return bc_stringref;
2338 case _cldc: case _cldc_w:
2339 return bc_classref;
2340 }
2341 break;
2342 }
2343 assert(false);
2344 return null;
2345 }
2346
2347 protected CPRefBand selfOpRefBand(int self_bc) {
2348 assert(Instruction.isSelfLinkerOp(self_bc));
2349 int idx = (self_bc - _self_linker_op);
2350 boolean isSuper = (idx >= _self_linker_super_flag);
2351 if (isSuper) idx -= _self_linker_super_flag;
2352 boolean isAload = (idx >= _self_linker_aload_flag);
2353 if (isAload) idx -= _self_linker_aload_flag;
2354 int origBC = _first_linker_op + idx;
2355 boolean isField = Instruction.isFieldOp(origBC);
2356 if (!isSuper)
2357 return isField? bc_thisfield: bc_thismethod;
2358 else
2359 return isField? bc_superfield: bc_supermethod;
2360 }
2361
2362
2363
2364 static int nextSeqForDebug;
2365 static File dumpDir = null;
2366 static OutputStream getDumpStream(Band b, String ext) throws IOException {
2367 return getDumpStream(b.name, b.seqForDebug, ext, b);
2368 }
2369 static OutputStream getDumpStream(Index ix, String ext) throws IOException {
2370 if (ix.size() == 0) return new ByteArrayOutputStream();
2371 int seq = ConstantPool.TAG_ORDER[ix.cpMap[0].tag];
2372 return getDumpStream(ix.debugName, seq, ext, ix);
2373 }
2374 static OutputStream getDumpStream(String name, int seq, String ext, Object b) throws IOException {
2375 if (dumpDir == null) {
2376 dumpDir = File.createTempFile("BD_", "", new File("."));
2377 dumpDir.delete();
2378 if (dumpDir.mkdir())
2379 Utils.log.info("Dumping bands to "+dumpDir);
2380 }
2381 name = name.replace('(', ' ').replace(')', ' ');
2382 name = name.replace('/', ' ');
2383 name = name.replace('*', ' ');
2384 name = name.trim().replace(' ','_');
2385 name = ((10000+seq) + "_" + name).substring(1);
2386 File dumpFile = new File(dumpDir, name+ext);
2387 Utils.log.info("Dumping "+b+" to "+dumpFile);
2388 return new BufferedOutputStream(new FileOutputStream(dumpFile));
2389 }
2390
2391
2392 static boolean assertCanChangeLength(Band b) {
2393 switch (b.phase) {
2394 case COLLECT_PHASE:
2395 case READ_PHASE:
2396 return true;
2397 }
2398 return false;
2399 }
2400
2401
2402 static boolean assertPhase(Band b, int phaseExpected) {
2403 if (b.phase() != phaseExpected) {
2404 Utils.log.warning("phase expected "+phaseExpected+" was "+b.phase()+" in "+b);
2405 return false;
2406 }
2407 return true;
2408 }
2409
2410
2411
2412 static int verbose() {
2413 return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE);
2414 }
2415
2416
2417
2418 static boolean assertPhaseChangeOK(Band b, int p0, int p1) {
2419 switch (p0*10+p1) {
2420
2421 case NO_PHASE*10+COLLECT_PHASE:
2422
2423 assert(!b.isReader());
2424 assert(b.capacity() >= 0);
2425 assert(b.length() == 0);
2426 return true;
2427 case COLLECT_PHASE*10+FROZEN_PHASE:
2428 case FROZEN_PHASE*10+FROZEN_PHASE:
2429 assert(b.length() == 0);
2430 return true;
2431 case COLLECT_PHASE*10+WRITE_PHASE:
2432 case FROZEN_PHASE*10+WRITE_PHASE:
2433
2434 return true;
2435 case WRITE_PHASE*10+DONE_PHASE:
2436
2437 return true;
2438
2439
2440 case NO_PHASE*10+EXPECT_PHASE:
2441 assert(b.isReader());
2442 assert(b.capacity() < 0);
2443 return true;
2444 case EXPECT_PHASE*10+READ_PHASE:
2445
2446 assert(Math.max(0,b.capacity()) >= b.valuesExpected());
2447 assert(b.length() <= 0);
2448 return true;
2449 case READ_PHASE*10+DISBURSE_PHASE:
2450
2451 assert(b.valuesRemainingForDebug() == b.length());
2452 return true;
2453 case DISBURSE_PHASE*10+DONE_PHASE:
2454
2455 assert(assertDoneDisbursing(b));
2456 return true;
2457 }
2458 if (p0 == p1)
2459 Utils.log.warning("Already in phase "+p0);
2460 else
2461 Utils.log.warning("Unexpected phase "+p0+" -> "+p1);
2462 return false;
2463 }
2464
2465 static private boolean assertDoneDisbursing(Band b) {
2466 if (b.phase != DISBURSE_PHASE) {
2467 Utils.log.warning("assertDoneDisbursing: still in phase "+b.phase+": "+b);
2468 if (verbose() <= 1) return false;
2469 }
2470 int left = b.valuesRemainingForDebug();
2471 if (left > 0) {
2472 Utils.log.warning("assertDoneDisbursing: "+left+" values left in "+b);
2473 if (verbose() <= 1) return false;
2474 }
2475 if (b instanceof MultiBand) {
2476 MultiBand mb = (MultiBand) b;
2477 for (int i = 0; i < mb.bandCount; i++) {
2478 Band sub = mb.bands[i];
2479 if (sub.phase != DONE_PHASE) {
2480 Utils.log.warning("assertDoneDisbursing: sub-band still in phase "+sub.phase+": "+sub);
2481 if (verbose() <= 1) return false;
2482 }
2483 }
2484 }
2485 return true;
2486 }
2487
2488 static private void printCDecl(Band b) {
2489 if (b instanceof MultiBand) {
2490 MultiBand mb = (MultiBand) b;
2491 for (int i = 0; i < mb.bandCount; i++) {
2492 printCDecl(mb.bands[i]);
2493 }
2494 return;
2495 }
2496 String ixS = "NULL";
2497 if (b instanceof CPRefBand) {
2498 Index ix = ((CPRefBand)b).index;
2499 if (ix != null) ixS = "INDEX("+ix.debugName+")";
2500 }
2501 Coding[] knownc = { BYTE1, CHAR3, BCI5, BRANCH5, UNSIGNED5,
2502 UDELTA5, SIGNED5, DELTA5, MDELTA5 };
2503 String[] knowns = { "BYTE1", "CHAR3", "BCI5", "BRANCH5", "UNSIGNED5",
2504 "UDELTA5", "SIGNED5", "DELTA5", "MDELTA5" };
2505 Coding rc = b.regularCoding;
2506 int rci = Arrays.asList(knownc).indexOf(rc);
2507 String cstr;
2508 if (rci >= 0)
2509 cstr = knowns[rci];
2510 else
2511 cstr = "CODING"+rc.keyString();
2512 System.out.println(" BAND_INIT(\""+b.name()+"\""
2513 +", "+cstr+", "+ixS+"),");
2514 }
2515
2516 private Map<Band, Band> prevForAssertMap;
2517
2518
2519 boolean notePrevForAssert(Band b, Band p) {
2520 if (prevForAssertMap == null)
2521 prevForAssertMap = new HashMap<>();
2522 prevForAssertMap.put(b, p);
2523 return true;
2524 }
2525
2526
2527 private boolean assertReadyToReadFrom(Band b, InputStream in) throws IOException {
2528 Band p = prevForAssertMap.get(b);
2529
2530 if (p != null && phaseCmp(p.phase(), DISBURSE_PHASE) < 0) {
2531 Utils.log.warning("Previous band not done reading.");
2532 Utils.log.info(" Previous band: "+p);
2533 Utils.log.info(" Next band: "+b);
2534 Thread.dumpStack();
2535 assert(verbose > 0);
2536 }
2537 String name = b.name;
2538 if (optDebugBands && !name.startsWith("(")) {
2539
2540 StringBuilder buf = new StringBuilder();
2541 int ch;
2542 while ((ch = in.read()) > 0)
2543 buf.append((char)ch);
2544 String inName = buf.toString();
2545 if (!inName.equals(name)) {
2546 StringBuilder sb = new StringBuilder();
2547 sb.append("Expected "+name+" but read: ");
2548 inName += (char)ch;
2549 while (inName.length() < 10) {
2550 inName += (char) in.read();
2551 }
2552 for (int i = 0; i < inName.length(); i++) {
2553 sb.append(inName.charAt(i));
2554 }
2555 Utils.log.warning(sb.toString());
2556 return false;
2557 }
2558 }
2559 return true;
2560 }
2561
2562
2563 private boolean assertValidCPRefs(CPRefBand b) {
2564 if (b.index == null) return true;
2565 int limit = b.index.size()+1;
2566 for (int i = 0; i < b.length(); i++) {
2567 int v = b.valueAtForDebug(i);
2568 if (v < 0 || v >= limit) {
2569 Utils.log.warning("CP ref out of range "+
2570 "["+i+"] = "+v+" in "+b);
2571 return false;
2572 }
2573 }
2574 return true;
2575 }
2576
2577
2578 private boolean assertReadyToWriteTo(Band b, OutputStream out) throws IOException {
2579 Band p = prevForAssertMap.get(b);
2580
2581 if (p != null && phaseCmp(p.phase(), DONE_PHASE) < 0) {
2582 Utils.log.warning("Previous band not done writing.");
2583 Utils.log.info(" Previous band: "+p);
2584 Utils.log.info(" Next band: "+b);
2585 Thread.dumpStack();
2586 assert(verbose > 0);
2587 }
2588 String name = b.name;
2589 if (optDebugBands && !name.startsWith("(")) {
2590
2591 for (int j = 0; j < name.length(); j++) {
2592 out.write((byte)name.charAt(j));
2593 }
2594 out.write((byte)0);
2595 }
2596 return true;
2597 }
2598
2599 protected static boolean testBit(int flags, int bitMask) {
2600 return (flags & bitMask) != 0;
2601 }
2602 protected static int setBit(int flags, int bitMask, boolean z) {
2603 return z ? (flags | bitMask) : (flags &~ bitMask);
2604 }
2605 protected static boolean testBit(long flags, long bitMask) {
2606 return (flags & bitMask) != 0;
2607 }
2608 protected static long setBit(long flags, long bitMask, boolean z) {
2609 return z ? (flags | bitMask) : (flags &~ bitMask);
2610 }
2611
2612
2613 static void printArrayTo(PrintStream ps, int[] values, int start, int end) {
2614 int len = end-start;
2615 for (int i = 0; i < len; i++) {
2616 if (i % 10 == 0)
2617 ps.println();
2618 else
2619 ps.print(" ");
2620 ps.print(values[start+i]);
2621 }
2622 ps.println();
2623 }
2624
2625 static void printArrayTo(PrintStream ps, Entry[] cpMap, int start, int end) {
2626 StringBuffer buf = new StringBuffer();
2627 int len = end-start;
2628 for (int i = 0; i < len; i++) {
2629 String s = cpMap[start+i].stringValue();
2630 buf.setLength(0);
2631 for (int j = 0; j < s.length(); j++) {
2632 char ch = s.charAt(j);
2633 if (!(ch < ' ' || ch > '~' || ch == '\\')) {
2634 buf.append(ch);
2635 } else if (ch == '\n') {
2636 buf.append("\\n");
2637 } else if (ch == '\t') {
2638 buf.append("\\t");
2639 } else if (ch == '\r') {
2640 buf.append("\\r");
2641 } else {
2642 buf.append("\\x"+Integer.toHexString(ch));
2643 }
2644 }
2645 ps.println(buf);
2646 }
2647 }
2648
2649
2650
2651 protected static Object[] realloc(Object[] a, int len) {
2652 java.lang.Class elt = a.getClass().getComponentType();
2653 Object[] na = (Object[]) java.lang.reflect.Array.newInstance(elt, len);
2654 System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
2655 return na;
2656 }
2657 protected static Object[] realloc(Object[] a) {
2658 return realloc(a, Math.max(10, a.length*2));
2659 }
2660
2661 protected static int[] realloc(int[] a, int len) {
2662 if (len == 0) return noInts;
2663 if (a == null) return new int[len];
2664 int[] na = new int[len];
2665 System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
2666 return na;
2667 }
2668 protected static int[] realloc(int[] a) {
2669 return realloc(a, Math.max(10, a.length*2));
2670 }
2671
2672 protected static byte[] realloc(byte[] a, int len) {
2673 if (len == 0) return noBytes;
2674 if (a == null) return new byte[len];
2675 byte[] na = new byte[len];
2676 System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
2677 return na;
2678 }
2679 protected static byte[] realloc(byte[] a) {
2680 return realloc(a, Math.max(10, a.length*2));
2681 }
2682 }